diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/english.js | 2 | ||||
| -rw-r--r-- | src/lib/invoice.js | 53 | ||||
| -rw-r--r-- | src/lib/nostr.js | 206 | ||||
| -rw-r--r-- | src/lib/punks.js | 128 | ||||
| -rw-r--r-- | src/lib/samples.js | 26 | ||||
| -rw-r--r-- | src/lib/socket.js | 114 | ||||
| -rw-r--r-- | src/lib/store.js | 66 | ||||
| -rw-r--r-- | src/lib/ticket.js | 50 | ||||
| -rw-r--r-- | src/lib/tickets.js | 100 | ||||
| -rw-r--r-- | src/lib/translations/index.js | 111 | ||||
| -rw-r--r-- | src/lib/translations/lang.json | 16 | ||||
| -rw-r--r-- | src/lib/upload.js | 32 | ||||
| -rw-r--r-- | src/lib/utils.js | 396 |
13 files changed, 676 insertions, 624 deletions
diff --git a/src/lib/english.js b/src/lib/english.js index d6c205d9..52a0da82 100644 --- a/src/lib/english.js +++ b/src/lib/english.js @@ -2045,4 +2045,4 @@ youth zebra zero zone -zoo`.split('\n'); +zoo`.split("\n"); diff --git a/src/lib/invoice.js b/src/lib/invoice.js index 218972c6..87707c89 100644 --- a/src/lib/invoice.js +++ b/src/lib/invoice.js @@ -1,36 +1,37 @@ -import { auth, get, post } from '$lib/utils'; -import { redirect } from '@sveltejs/kit'; +import { auth, get, post } from "$lib/utils"; +import { redirect } from "@sveltejs/kit"; export default async ({ cookies, request, url }) => { - let form = await request.formData(); + let form = await request.formData(); - let rates = await get('/rates'); - let amount = parseInt(form.get('amount')); - let request_id = form.get('request_id'); - if (request_id === 'undefined') request_id = undefined; + let rates = await get("/rates"); + let amount = parseInt(form.get("amount")); + let request_id = form.get("request_id"); + if (request_id === "undefined") request_id = undefined; - let invoice = { - amount, - tip: parseInt(form.get('tip')) || 0, - type: form.get('type'), - prompt: form.get('prompt') === 'true', - rate: parseFloat(form.get('rate')) || rates[form.get('currency')], - request_id - }; + let invoice = { + amount, + tip: parseInt(form.get("tip")) || 0, + type: form.get("type"), + prompt: form.get("prompt") === "true", + rate: parseFloat(form.get("rate")) || rates[form.get("currency")], + request_id, + }; - let user = { username: form.get('username'), currency: form.get('currency') }; + let user = { username: form.get("username"), currency: form.get("currency") }; - invoice = await post('/invoice', { invoice, user }, auth(cookies)); - let { id } = invoice; + invoice = await post("/invoice", { invoice, user }, auth(cookies)); + let { id } = invoice; - if (request_id) { - if (url.pathname.endsWith('tip')) { - throw redirect(307, `/send/invoice/${id}`); - } + if (request_id) { + if (url.pathname.endsWith("tip")) { + throw redirect(307, `/send/invoice/${id}`); + } - throw redirect(307, `/${user.username}/request/${request_id}`); - } + throw redirect(307, `/${user.username}/request/${request_id}`); + } - if (invoice.prompt) throw redirect(307, `/${user.username}/invoice/${id}/tip`); - else throw redirect(307, `/${user.username}/invoice/${id}`); + if (invoice.prompt) + throw redirect(307, `/${user.username}/invoice/${id}/tip`); + else throw redirect(307, `/${user.username}/invoice/${id}`); }; diff --git a/src/lib/nostr.js b/src/lib/nostr.js index c2634c83..5ab87e51 100644 --- a/src/lib/nostr.js +++ b/src/lib/nostr.js @@ -1,144 +1,164 @@ -import { get } from 'svelte/store'; -import { Buffer } from 'buffer'; -import { fail, wait, post, stretch } from '$lib/utils'; -import { decrypted, password as pw, passwordPrompt, pin, loginRedirect } from '$lib/store'; -import { goto, invalidate } from '$app/navigation'; -import { getPublicKey, signEvent, getEventHash, nip04, nip06, nip19 } from 'nostr-tools'; -import { mnemonicToEntropy, entropyToMnemonic } from '@scure/bip39'; -import wordlist from '$lib/english'; -import { bech32m } from '@scure/base'; +import { get } from "svelte/store"; +import { Buffer } from "buffer"; +import { fail, wait, post, stretch } from "$lib/utils"; +import { + decrypted, + password as pw, + passwordPrompt, + pin, + loginRedirect, +} from "$lib/store"; +import { goto, invalidate } from "$app/navigation"; +import { + getPublicKey, + signEvent, + getEventHash, + nip04, + nip06, + nip19, +} from "nostr-tools"; +import { mnemonicToEntropy, entropyToMnemonic } from "@scure/bip39"; +import wordlist from "$lib/english"; +import { bech32m } from "@scure/base"; const { generateSeedWords, privateKeyFromSeedWords } = nip06; const { encode, decode, toWords, fromWords } = bech32m; export let generate = async (user) => { - if (!get(pin)?.length === 6) return; - let password = get(pw); + if (!get(pin)?.length === 6) return; + let password = get(pw); - let salt = crypto.getRandomValues(new Uint8Array(16)); - let mnemonic = generateSeedWords(); - let sk = privateKeyFromSeedWords(mnemonic); + let salt = crypto.getRandomValues(new Uint8Array(16)); + let mnemonic = generateSeedWords(); + let sk = privateKeyFromSeedWords(mnemonic); - let bytes = new Uint8Array( - await crypto.subtle.encrypt( - { name: 'AES-GCM', iv: new Uint8Array(16) }, - await stretch(password, salt), - Uint8Array.from(Buffer.from(mnemonicToEntropy(mnemonic, wordlist), 'hex')) - ) - ); + let bytes = new Uint8Array( + await crypto.subtle.encrypt( + { name: "AES-GCM", iv: new Uint8Array(16) }, + await stretch(password, salt), + Uint8Array.from(Buffer.from(mnemonicToEntropy(mnemonic, wordlist), "hex")) + ) + ); - user.pubkey = getPublicKey(sk); - user.cipher = encode('en', toWords(bytes), 180); - user.salt = Buffer.from(salt).toString('hex'); + user.pubkey = getPublicKey(sk); + user.cipher = encode("en", toWords(bytes), 180); + user.salt = Buffer.from(salt).toString("hex"); }; export let encrypt = async ({ message, recipient, user }) => { - return nip04.encrypt(await getPrivateKey(user), recipient, message); + return nip04.encrypt(await getPrivateKey(user), recipient, message); }; export let decrypt = async ({ event, user }) => { - let cache = get(decrypted); - try { - let { content, pubkey, id } = event; - if (cache[id]) return cache[id]; - if (pubkey === user.pubkey) pubkey = event.tags[0][1]; + let cache = get(decrypted); + try { + let { content, pubkey, id } = event; + if (cache[id]) return cache[id]; + if (pubkey === user.pubkey) pubkey = event.tags[0][1]; - let message = await nip04.decrypt(await getPrivateKey(user), pubkey, content); + let message = await nip04.decrypt( + await getPrivateKey(user), + pubkey, + content + ); - cache[id] = Buffer.from(message).toString('utf8'); - decrypted.set(cache); + cache[id] = Buffer.from(message).toString("utf8"); + decrypted.set(cache); - return cache[id]; - } catch (e) { - // console.log(e); - } + return cache[id]; + } catch (e) { + // console.log(e); + } }; function typedArrayToBuffer(array) { - return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset); + return array.buffer.slice( + array.byteOffset, + array.byteLength + array.byteOffset + ); } export let getMnemonic = async (user) => { - let { cipher, username, salt } = user; - let password = get(pw); + let { cipher, username, salt } = user; + let password = get(pw); - if (!password) { - passwordPrompt.set(true); - } + if (!password) { + passwordPrompt.set(true); + } - try { - await post('/password', { password }); - } catch (e) { - passwordPrompt.set(true); - } + try { + await post("/password", { password }); + } catch (e) { + passwordPrompt.set(true); + } - await wait(() => !!get(pw)); - password = get(pw); + await wait(() => !!get(pw)); + password = get(pw); - let mnemonic, key, seed, entropy, child, privkey; + let mnemonic, key, seed, entropy, child, privkey; - entropy = new Uint8Array( - await crypto.subtle.decrypt( - { name: 'AES-GCM', iv: new Uint8Array(16) }, - await stretch(password, Buffer.from(salt, 'hex')), - Uint8Array.from(fromWords(decode(cipher, 180).words)) - ) - ); + entropy = new Uint8Array( + await crypto.subtle.decrypt( + { name: "AES-GCM", iv: new Uint8Array(16) }, + await stretch(password, Buffer.from(salt, "hex")), + Uint8Array.from(fromWords(decode(cipher, 180).words)) + ) + ); - return entropyToMnemonic(entropy, wordlist); + return entropyToMnemonic(entropy, wordlist); }; let getPrivateKey = async (user) => { - return privateKeyFromSeedWords(await getMnemonic(user)); + return privateKeyFromSeedWords(await getMnemonic(user)); }; export let getNsec = async (user) => { - return nip19.nsecEncode(await getPrivateKey(user)); + return nip19.nsecEncode(await getPrivateKey(user)); }; export let sign = async ({ event, user }) => { - event.id = getEventHash(event); - event.sig = signEvent(event, await getPrivateKey(user)); + event.id = getEventHash(event); + event.sig = signEvent(event, await getPrivateKey(user)); }; export let send = (event) => { - return post('/events', { event }); + return post("/events", { event }); }; export let reEncryptEntropy = async (user, newPassword) => { - let { cipher, username, salt } = user; - let password = get(pw); + let { cipher, username, salt } = user; + let password = get(pw); - if (!password) { - passwordPrompt.set(true); - } + if (!password) { + passwordPrompt.set(true); + } - try { - await post('/password', { password }); - } catch (e) { - passwordPrompt.set(true); - } + try { + await post("/password", { password }); + } catch (e) { + passwordPrompt.set(true); + } - await wait(() => !!get(pw)); - password = get(pw); + await wait(() => !!get(pw)); + password = get(pw); - let mnemonic, key, seed, entropy, child, privkey; - entropy = Buffer.from( - await crypto.subtle.decrypt( - { name: 'AES-GCM', iv: new Uint8Array(16) }, - await stretch(password, Buffer.from(salt, 'hex')), - Uint8Array.from(fromWords(decode(cipher, 180).words)) - ), - 'hex' - ).toString('hex'); + let mnemonic, key, seed, entropy, child, privkey; + entropy = Buffer.from( + await crypto.subtle.decrypt( + { name: "AES-GCM", iv: new Uint8Array(16) }, + await stretch(password, Buffer.from(salt, "hex")), + Uint8Array.from(fromWords(decode(cipher, 180).words)) + ), + "hex" + ).toString("hex"); - let bytes = new Uint8Array( - await crypto.subtle.encrypt( - { name: 'AES-GCM', iv: new Uint8Array(16) }, - await stretch(newPassword, Buffer.from(salt, 'hex')), - Uint8Array.from(Buffer.from(entropy, 'hex')) - ) - ); + let bytes = new Uint8Array( + await crypto.subtle.encrypt( + { name: "AES-GCM", iv: new Uint8Array(16) }, + await stretch(newPassword, Buffer.from(salt, "hex")), + Uint8Array.from(Buffer.from(entropy, "hex")) + ) + ); - return encode('en', toWords(bytes), 180); + return encode("en", toWords(bytes), 180); }; diff --git a/src/lib/punks.js b/src/lib/punks.js index a87feb1f..e5551062 100644 --- a/src/lib/punks.js +++ b/src/lib/punks.js @@ -1,66 +1,66 @@ export default [ - '6e1f1626a9308abd0b7732fecbc7d49366ced46dead63ef3603fb0f4ec7aa53d', - '96ea95735b61c48c6f465db8ca0246a62539f34c3a977be6338770d92461da89', - '8c18c036b257d7b9c5a970a786efa04c320f3cf5afa73fa310a6603744d1ee3a', - 'a7a6187e54e83acdb893d456c8b4ad6877e4738ea9e0d47c9b2070bf2c98a35f', - '836d72150b6f3033b6220d15ac9d49457d81041a700d12898bd3b8e737b4d265', - 'e3d1c40538a8aed282a430647e3ff16ff94b64b8ed0a7cf427e8b0e2780a9b2a', - '2155224ef35cfb4bbdb06d982b42bb9b93d97b2bc691c22c804e1759a0a04882', - '5f6549ad9dd15dd57c204b1a9b60c68c376e77d7d114cfa13219e6a1a71f901f', - 'ba8dd5a7070aee7102d4f8bc83ac497091e2e473a0f448a1c513569167dd0791', - '4f07e1da3685a858970a9f39300564971e97257f5d37b55a6d9882014aecc421', - '01aa9348244c4b65de3df758d49c98076e17a109aef04bc211abc77cf42dc51d', - '080574eb9e0613926e0e5d9b667c132e12965a1b1d47218a0b290a2d55c55d2f', - '08ce4840184f63a779bcd1f91bbcb56a2e8cba75c3ba2dbd290a559a57e4238e', - '27caa38c14a85ad64b4c4469a34e61a3965a1cbc4cad9a85707da374301c830d', - 'eccc90741370ba4acc70bc65f4ccc38fddb1327d977c366156018974bc52fe4a', - '3759946d9e875ac2fc5c51ed850686193bb1e0716219e42efd52f3965993b275', - 'db5fe28b8ddb9ae5e4f5e0e757ee60bc938bffbdfdd38de807939e212d3c5066', - '3f8f861e663accee51e68b987705ce647a7446b7f118abc94c632e158acbb44f', - '43bab95a047112dca6705506f916a97252363a20da4a4c0a5ab7b676e11083fc', - 'd3018e45c66dd485697f738ad191af98267e6255d562496dd06b1a662e0c7a88', - '0ec2e8d07e053d686140857493ece653cde52764a60aa1d25651d81811d44a3d', - '4595bb092682af7177799464364c047fbfa7ede767336734949bce5d085fce15', - '6524936709e0719f9e28bf1caac91f86f323d1a79f10ab65a03fa9ea2e6b3270', - '8ba4736edc68da8e5b21c23af4de1f9131f47778c2a5b2a970a799223a9380b3', - '2aaba839e8546a8cb6d04a81ff5be83ac4e700ca4491607a16ebd60dc4995750', - '5f88f7f579ce50d7bcf60d6e9556f77acf361ba54caf3eb61dc4f2ca9c94c6a2', - 'd1ca262272613d7386fecce7f1ad268188940b59ea83fdd1f8d7ab85771e3f43', - '5211890e4128d8d730802cc75ee105867e8878581d5e72ffc98a0d60027a5398', - 'c1dececcbd7b623bfaa726392512e6ea110db93a0649dd01bf9e559318514f7c', - '43ce93c9835e983403a01329918d184832c5516e1b0ea4e0878b4c4def042777', - 'c84724a398bda8d20436fb0663d059c196628fa71192bb720fa5adf6137bed9b', - 'f307620a90a36045fa550316d61be4755c1f6c7f3fc81c95fc4d590ac568b2c4', - '78ae0118856a1f17c13f292628fcf3dccc150c7278578caaceb9f35ca8bc9f55', - '9d9a9a40c490f05d7dbafde8bf60d68aab7dcb79a7976eef62d1448a4549816b', - 'f6017bec50563dbbb24b979214ae225f96b01dea5b090b174038ff2842a1c6b1', - '6dbec748ea87e959390b0df429c005fccffe9e672864f555c14c7a407b940870', - '11701e76233395ebdba8d1d50334d1a0cc3a158f3452260c9a7b9a067b78d753', - '7354f3829dd05c838aa16d66b00316f7994797927a4d3b594c8af04a2b4ae86a', - '14d254333c6240fbdacbbbe261f7ae15be2e83bffcf084f4f59f459bae0a4571', - '7849ac0f31056265efb0110038f86e61effe17b7db836377d88433b73312e65a', - '9018be885177c675baf9b36978428d841ca30a9185e11de1a31238a08e3ec1af', - '777c5715de7423597fea6c03c496ea46414f0508cd96e119261f002965beb805', - 'b742b7509a97c2b346ea762f0510e8475b30dc988417f0f146ae00a800c6dd56', - '7af3029a826e6dfba23ad502901a3632ef4ee047bd45d618b1f106717b0af7ea', - '82390020b2bca461204cc49b20ee6fec1b93dad476726f377785d04040a4d6c3', - '6bc2990699be7f610c9f6a49bc7a19b034040727bc3de63fee89a1573fe00673', - '50c7c2e8e8c7f4aabffb195187a1ac1105f5712859f02d491d794ba2d8498e08', - '5d1d3769cd141603ce907df5dca159e389ca4d75338eddbe1b7db1c0766cbfd6', - '4d8ad7a761d068b7ef9b058fb4ba924b276e7a45a3ad47a79b767e08e821e038', - 'd5b5b2167602f7277cdac76cfda8bdad0befcb8ff12df495dfabf40c91d1120c', - '6f2618272bb0164247e9b0f40b19f020c1c9253510dc658a3cc078d079ef01bf', - 'fd502d5007bfc62a91eb7a34c1ae23b9de4a20cf5e1bbd86dadc421d7083099c', - '914813583b901044970b9c7d6dcdfde4344339325f5988d0dd681d377f1243fb', - '85cb7cf0245613d08b3027f879f58a6db645bf0db107242beb856b340ee49ee8', - 'd6dbb18d5df5e92c8c74ee59aa86d19dff25a5d0f9d030e84285a686f86804d7', - '65309f82cd9f9926a578d09e1ad13909f68a06d02b853760731a4225f7aecef4', - '433519d13f2b64fe82a90cd054797d4779507fea93c1054bd51c35ba846a0f7f', - '62a55d4d6e4b6f992a1c1840f041585c957affcdbf875202cf9e1db9def05aeb', - 'e19eb1eeabdeffa04ccd792eb09776690cf2121887b26a7c5d20d66e3e8fd0fb', - 'a80951fc593035abb2dda045a2076d29a30f5cc470e0a20db39c3ec588ed61d8', - '4f1b39906714266a7a1936bfa8e08c5d891285dd2b188b4bcd4afb0107671004', - 'f46310b2e60727af071d09e759814f52f933688a0ff0995c7da373b381e70005', - '2cc94821f56d21918ba4f2770d97f280e06fd99f4199167e2f4ddc780f404c8a', - '698a2ca7a09e88fa6594801da037f4dbce6ae841d1d33736aebcf8f6fe104e01', + "6e1f1626a9308abd0b7732fecbc7d49366ced46dead63ef3603fb0f4ec7aa53d", + "96ea95735b61c48c6f465db8ca0246a62539f34c3a977be6338770d92461da89", + "8c18c036b257d7b9c5a970a786efa04c320f3cf5afa73fa310a6603744d1ee3a", + "a7a6187e54e83acdb893d456c8b4ad6877e4738ea9e0d47c9b2070bf2c98a35f", + "836d72150b6f3033b6220d15ac9d49457d81041a700d12898bd3b8e737b4d265", + "e3d1c40538a8aed282a430647e3ff16ff94b64b8ed0a7cf427e8b0e2780a9b2a", + "2155224ef35cfb4bbdb06d982b42bb9b93d97b2bc691c22c804e1759a0a04882", + "5f6549ad9dd15dd57c204b1a9b60c68c376e77d7d114cfa13219e6a1a71f901f", + "ba8dd5a7070aee7102d4f8bc83ac497091e2e473a0f448a1c513569167dd0791", + "4f07e1da3685a858970a9f39300564971e97257f5d37b55a6d9882014aecc421", + "01aa9348244c4b65de3df758d49c98076e17a109aef04bc211abc77cf42dc51d", + "080574eb9e0613926e0e5d9b667c132e12965a1b1d47218a0b290a2d55c55d2f", + "08ce4840184f63a779bcd1f91bbcb56a2e8cba75c3ba2dbd290a559a57e4238e", + "27caa38c14a85ad64b4c4469a34e61a3965a1cbc4cad9a85707da374301c830d", + "eccc90741370ba4acc70bc65f4ccc38fddb1327d977c366156018974bc52fe4a", + "3759946d9e875ac2fc5c51ed850686193bb1e0716219e42efd52f3965993b275", + "db5fe28b8ddb9ae5e4f5e0e757ee60bc938bffbdfdd38de807939e212d3c5066", + "3f8f861e663accee51e68b987705ce647a7446b7f118abc94c632e158acbb44f", + "43bab95a047112dca6705506f916a97252363a20da4a4c0a5ab7b676e11083fc", + "d3018e45c66dd485697f738ad191af98267e6255d562496dd06b1a662e0c7a88", + "0ec2e8d07e053d686140857493ece653cde52764a60aa1d25651d81811d44a3d", + "4595bb092682af7177799464364c047fbfa7ede767336734949bce5d085fce15", + "6524936709e0719f9e28bf1caac91f86f323d1a79f10ab65a03fa9ea2e6b3270", + "8ba4736edc68da8e5b21c23af4de1f9131f47778c2a5b2a970a799223a9380b3", + "2aaba839e8546a8cb6d04a81ff5be83ac4e700ca4491607a16ebd60dc4995750", + "5f88f7f579ce50d7bcf60d6e9556f77acf361ba54caf3eb61dc4f2ca9c94c6a2", + "d1ca262272613d7386fecce7f1ad268188940b59ea83fdd1f8d7ab85771e3f43", + "5211890e4128d8d730802cc75ee105867e8878581d5e72ffc98a0d60027a5398", + "c1dececcbd7b623bfaa726392512e6ea110db93a0649dd01bf9e559318514f7c", + "43ce93c9835e983403a01329918d184832c5516e1b0ea4e0878b4c4def042777", + "c84724a398bda8d20436fb0663d059c196628fa71192bb720fa5adf6137bed9b", + "f307620a90a36045fa550316d61be4755c1f6c7f3fc81c95fc4d590ac568b2c4", + "78ae0118856a1f17c13f292628fcf3dccc150c7278578caaceb9f35ca8bc9f55", + "9d9a9a40c490f05d7dbafde8bf60d68aab7dcb79a7976eef62d1448a4549816b", + "f6017bec50563dbbb24b979214ae225f96b01dea5b090b174038ff2842a1c6b1", + "6dbec748ea87e959390b0df429c005fccffe9e672864f555c14c7a407b940870", + "11701e76233395ebdba8d1d50334d1a0cc3a158f3452260c9a7b9a067b78d753", + "7354f3829dd05c838aa16d66b00316f7994797927a4d3b594c8af04a2b4ae86a", + "14d254333c6240fbdacbbbe261f7ae15be2e83bffcf084f4f59f459bae0a4571", + "7849ac0f31056265efb0110038f86e61effe17b7db836377d88433b73312e65a", + "9018be885177c675baf9b36978428d841ca30a9185e11de1a31238a08e3ec1af", + "777c5715de7423597fea6c03c496ea46414f0508cd96e119261f002965beb805", + "b742b7509a97c2b346ea762f0510e8475b30dc988417f0f146ae00a800c6dd56", + "7af3029a826e6dfba23ad502901a3632ef4ee047bd45d618b1f106717b0af7ea", + "82390020b2bca461204cc49b20ee6fec1b93dad476726f377785d04040a4d6c3", + "6bc2990699be7f610c9f6a49bc7a19b034040727bc3de63fee89a1573fe00673", + "50c7c2e8e8c7f4aabffb195187a1ac1105f5712859f02d491d794ba2d8498e08", + "5d1d3769cd141603ce907df5dca159e389ca4d75338eddbe1b7db1c0766cbfd6", + "4d8ad7a761d068b7ef9b058fb4ba924b276e7a45a3ad47a79b767e08e821e038", + "d5b5b2167602f7277cdac76cfda8bdad0befcb8ff12df495dfabf40c91d1120c", + "6f2618272bb0164247e9b0f40b19f020c1c9253510dc658a3cc078d079ef01bf", + "fd502d5007bfc62a91eb7a34c1ae23b9de4a20cf5e1bbd86dadc421d7083099c", + "914813583b901044970b9c7d6dcdfde4344339325f5988d0dd681d377f1243fb", + "85cb7cf0245613d08b3027f879f58a6db645bf0db107242beb856b340ee49ee8", + "d6dbb18d5df5e92c8c74ee59aa86d19dff25a5d0f9d030e84285a686f86804d7", + "65309f82cd9f9926a578d09e1ad13909f68a06d02b853760731a4225f7aecef4", + "433519d13f2b64fe82a90cd054797d4779507fea93c1054bd51c35ba846a0f7f", + "62a55d4d6e4b6f992a1c1840f041585c957affcdbf875202cf9e1db9def05aeb", + "e19eb1eeabdeffa04ccd792eb09776690cf2121887b26a7c5d20d66e3e8fd0fb", + "a80951fc593035abb2dda045a2076d29a30f5cc470e0a20db39c3ec588ed61d8", + "4f1b39906714266a7a1936bfa8e08c5d891285dd2b188b4bcd4afb0107671004", + "f46310b2e60727af071d09e759814f52f933688a0ff0995c7da373b381e70005", + "2cc94821f56d21918ba4f2770d97f280e06fd99f4199167e2f4ddc780f404c8a", + "698a2ca7a09e88fa6594801da037f4dbce6ae841d1d33736aebcf8f6fe104e01", ]; diff --git a/src/lib/samples.js b/src/lib/samples.js index ac9e2d7e..1a1f5d9c 100644 --- a/src/lib/samples.js +++ b/src/lib/samples.js @@ -1,32 +1,32 @@ export default { - register: `curl "https://coinos.io/api/register" -H "content-type: application/json" -d '{ + register: `curl "https://coinos.io/api/register" -H "content-type: application/json" -d '{ "user": { "username": "demo", "password": "hunter2" } }'`, - login: `curl "https://coinos.io/api/login" -H "content-type: application/json" -d '{ + login: `curl "https://coinos.io/api/login" -H "content-type: application/json" -d '{ "username": "demo", "password": "hunter2" }'`, - payments: `curl "https://coinos.io/api/payments" + payments: `curl "https://coinos.io/api/payments" -H "content-type: application/json" -H "Authorization: Bearer $token" `, - lightning: `curl "https://coinos.io/api/payments" + lightning: `curl "https://coinos.io/api/payments" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ "payreq": "lnbc1pj94d8fsp5n77k340ps4m9jn7kp8he8yynpddvurv6mcsrrqpnq5l2jxdxzlwqpp5m96pqhc5nrlk8cqsu9ufdxxa43sarp8vwf9egvm2pg9nl0zu9r8qdq2vdhkjmn0wvxqztgcqpjrzjqwhmav82kntsppmkp8jp4vg4h9nns78tsy8mg7ve4lq5txrkp0h56zlarvqqdtcqqsqqqqqqqqqqp6cq9q9qyysgqzxlypywzphyujm3ga5j5csfcmqvlnae0fgnvymkaaw94eeg7py5rqzysyjkr3ev2snq63qpsc69vf54adkd0szvmvwt5cuadjnuy95sq4xfa40" }'`, - bitcoin: `curl "https://coinos.io/api/payments" + bitcoin: `curl "https://coinos.io/api/payments" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ "amount": 5000, "hash": "bc1q3unh97w4rmelflrm2hvdwz37d8kray3vn4d5ca" }'`, - internal: `HASH=$(curl "https://coinos.io/api/invoice" + internal: `HASH=$(curl "https://coinos.io/api/invoice" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ @@ -46,10 +46,10 @@ export default { "amount": 5000, "hash": $HASH }'`, - rates: `curl "https://coinos.io/api/rates" + rates: `curl "https://coinos.io/api/rates" -H "content-type: application/json" }'`, - lightningInvoice: `curl "https://coinos.io/api/invoice" + lightningInvoice: `curl "https://coinos.io/api/invoice" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ @@ -58,7 +58,7 @@ export default { "type": "lightning" } }'`, - bitcoinAddress: `curl "https://coinos.io/api/invoice" + bitcoinAddress: `curl "https://coinos.io/api/invoice" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ @@ -67,7 +67,7 @@ export default { "type": "bitcoin" } }'`, - webhook: `curl "https://coinos.io/api/invoice" + webhook: `curl "https://coinos.io/api/invoice" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ @@ -77,9 +77,9 @@ export default { "secret": "webhooksecret" } }'`, - fetchInvoice: `curl "https://coinos.io/api/invoice/bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj" + fetchInvoice: `curl "https://coinos.io/api/invoice/bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj" -H "content-type: application/json"'`, - invoiceResponse: `{ + invoiceResponse: `{ "amount":3141 "tip":0 "type":"bitcoin" @@ -92,5 +92,5 @@ export default { "received":0 "created":1677537428134 }`, - socketAuth: `echo '{"type":"login","data":{"username":"user","password":"password"}}' | websocat -n https://coinos.io/ws` + socketAuth: `echo '{"type":"login","data":{"username":"user","password":"password"}}' | websocat -n https://coinos.io/ws`, }; diff --git a/src/lib/socket.js b/src/lib/socket.js index 96fde317..d51ab39b 100644 --- a/src/lib/socket.js +++ b/src/lib/socket.js @@ -1,50 +1,58 @@ -import { get } from 'svelte/store'; -import { event, invoice, request, newPayment, last, rate, user } from '$lib/store'; -import { success, sat } from '$lib/utils'; -import { PUBLIC_SOCKET } from '$env/static/public'; -import { invalidate } from '$app/navigation'; -import { browser } from '$app/environment'; +import { get } from "svelte/store"; +import { + event, + invoice, + request, + newPayment, + last, + rate, + user, +} from "$lib/store"; +import { success, sat } from "$lib/utils"; +import { PUBLIC_SOCKET } from "$env/static/public"; +import { invalidate } from "$app/navigation"; +import { browser } from "$app/environment"; let socket, token; -export const auth = () => token && send('login', token); +export const auth = () => token && send("login", token); export const send = (type, data) => { - socket?.readyState === 1 && socket.send(JSON.stringify({ type, data })); - return true; + socket?.readyState === 1 && socket.send(JSON.stringify({ type, data })); + return true; }; export const messages = (data) => ({ - id() { - last.set(Date.now()); - }, - invoice() { - invoice.set(data); - }, - event() { - event.set(data); - }, - rate() { - rate.set(data); - }, + id() { + last.set(Date.now()); + }, + invoice() { + invoice.set(data); + }, + event() { + event.set(data); + }, + rate() { + rate.set(data); + }, - request() { - request.set(data); - invalidate('app:invoice'); - }, + request() { + request.set(data); + invalidate("app:invoice"); + }, - async payment() { - let { amount, confirmed } = data; - invalidate('app:user'); - invalidate('app:invoice'); - invalidate('app:payments'); + async payment() { + let { amount, confirmed } = data; + invalidate("app:user"); + invalidate("app:invoice"); + invalidate("app:payments"); - if (amount > 0) { - success(`${confirmed ? 'Received' : 'Detected'} ${sat(amount)}!`); - } - }, + if (amount > 0) { + success(`${confirmed ? "Received" : "Detected"} ${sat(amount)}!`); + } + }, - connected: auth + connected: auth, }); const initialReconnectDelay = 1000; @@ -53,39 +61,39 @@ const maxReconnectDelay = 16000; let currentReconnectDelay = initialReconnectDelay; export function connect(t) { - token = t; + token = t; - if (socket) return auth(); + if (socket) return auth(); - socket = new WebSocket(PUBLIC_SOCKET); - socket.addEventListener('open', onWebsocketOpen); - socket.addEventListener('close', onWebsocketClose); - socket.addEventListener('message', onWebsocketMessage); + socket = new WebSocket(PUBLIC_SOCKET); + socket.addEventListener("open", onWebsocketOpen); + socket.addEventListener("close", onWebsocketClose); + socket.addEventListener("message", onWebsocketMessage); } export function close() { - if (socket) socket.close(); + if (socket) socket.close(); } function onWebsocketMessage(msg) { - let { type, data } = JSON.parse(msg.data); - messages(data)[type] && messages(data)[type](); + let { type, data } = JSON.parse(msg.data); + messages(data)[type] && messages(data)[type](); } function onWebsocketOpen() { - currentReconnectDelay = initialReconnectDelay; + currentReconnectDelay = initialReconnectDelay; } function onWebsocketClose() { - socket = null; - setTimeout(() => { - reconnectToWebsocket(); - }, currentReconnectDelay + Math.floor(Math.random() * 3000)); + socket = null; + setTimeout(() => { + reconnectToWebsocket(); + }, currentReconnectDelay + Math.floor(Math.random() * 3000)); } function reconnectToWebsocket() { - if (currentReconnectDelay < maxReconnectDelay) { - currentReconnectDelay *= 2; - } - connect(token); + if (currentReconnectDelay < maxReconnectDelay) { + currentReconnectDelay *= 2; + } + connect(token); } diff --git a/src/lib/store.js b/src/lib/store.js index 403ee816..2ae8c9b9 100644 --- a/src/lib/store.js +++ b/src/lib/store.js @@ -1,56 +1,60 @@ -import { get, writable } from 'svelte/store'; -import { browser } from '$app/environment'; +import { get, writable } from "svelte/store"; +import { browser } from "$app/environment"; const persistSession = (key, defaultValue) => { - let s = writable( - browser && sessionStorage.getItem(key) && sessionStorage.getItem(key) !== 'undefined' - ? JSON.parse(sessionStorage.getItem(key)) - : defaultValue - ); + let s = writable( + browser && + sessionStorage.getItem(key) && + sessionStorage.getItem(key) !== "undefined" + ? JSON.parse(sessionStorage.getItem(key)) + : defaultValue + ); - s.subscribe((v) => { - browser && sessionStorage.setItem(key, JSON.stringify(v)); - }); + s.subscribe((v) => { + browser && sessionStorage.setItem(key, JSON.stringify(v)); + }); - return s; + return s; }; const persistLocal = (key, defaultValue) => { - let s = writable( - browser && localStorage.getItem(key) && localStorage.getItem(key) !== 'undefined' - ? JSON.parse(localStorage.getItem(key)) - : defaultValue - ); + let s = writable( + browser && + localStorage.getItem(key) && + localStorage.getItem(key) !== "undefined" + ? JSON.parse(localStorage.getItem(key)) + : defaultValue + ); - s.subscribe((v) => { - try { - browser && localStorage.setItem(key, JSON.stringify(v)); - } catch (e) { - console.log('problem setting key', v); - console.log(e); - } - }); + s.subscribe((v) => { + try { + browser && localStorage.setItem(key, JSON.stringify(v)); + } catch (e) { + console.log("problem setting key", v); + console.log(e); + } + }); - return s; + return s; }; -export const animatedRate = persistLocal('rate', 0); +export const animatedRate = persistLocal("rate", 0); export const avatar = writable(); export const banner = writable(); -export const colorTheme = writable('from-primary to-gradient'); +export const colorTheme = writable("from-primary to-gradient"); export const event = writable(); export const events = writable({}); export const invoice = writable(); export const last = writable(); export const loginRedirect = writable(); -export const decrypted = persistLocal('decrypted', {}); -export const newPayment = persistLocal('newPayment'); +export const decrypted = persistLocal("decrypted", {}); +export const newPayment = persistLocal("newPayment"); export const password = writable(); export const passwordPrompt = writable(); -export const pin = persistSession('pin'); +export const pin = persistSession("pin"); export const rate = writable(); export const request = writable(); export const requestRedirect = writable(); -export const token = persistSession('token'); +export const token = persistSession("token"); export const user = writable(); export const ndef = writable(); diff --git a/src/lib/ticket.js b/src/lib/ticket.js index e1ebcb8c..73ef7716 100644 --- a/src/lib/ticket.js +++ b/src/lib/ticket.js @@ -1,31 +1,31 @@ -import { auth, get, post } from '$lib/utils'; -import { env } from '$env/dynamic/private'; -import tickets from '$lib/tickets'; +import { auth, get, post } from "$lib/utils"; +import { env } from "$env/dynamic/private"; +import tickets from "$lib/tickets"; export const createTicket = async (cookies, username) => { - let { ticket } = await get('/ticket'); + let { ticket } = await get("/ticket"); - let { address } = await post( - `/${username}/invoice`, - { invoice: { network: 'liquid' }, user: { username } }, - auth(cookies) - ); + let { address } = await post( + `/${username}/invoice`, + { invoice: { network: "liquid" }, user: { username } }, + auth(cookies) + ); - let { asset } = await post( - '/assets', - { - address, - name: `Launch Party Ticket ${ticket}`, - ticker: 'LPT', - precision: 0, - asset_amount: '1', - token_amount: 0, - domain: 'coinos.io', - filename: tickets[ticket] - }, - { authorization: `Bearer ${env.LAUNCH}` } - ); + let { asset } = await post( + "/assets", + { + address, + name: `Launch Party Ticket ${ticket}`, + ticker: "LPT", + precision: 0, + asset_amount: "1", + token_amount: 0, + domain: "coinos.io", + filename: tickets[ticket], + }, + { authorization: `Bearer ${env.LAUNCH}` } + ); - await post('/ticket', { asset }, { authorization: `Bearer ${env.LAUNCH}` }); - return asset; + await post("/ticket", { asset }, { authorization: `Bearer ${env.LAUNCH}` }); + return asset; }; diff --git a/src/lib/tickets.js b/src/lib/tickets.js index b0ca0ac0..1f8cbdac 100644 --- a/src/lib/tickets.js +++ b/src/lib/tickets.js @@ -1,52 +1,52 @@ export default [ - 'QmPbFkiXNuaQyfwD4W9GcXP7qWaNd6wFd9KCnJir5mes1J', - 'QmPVjvbaMxSJRpDxMLYTdUWQbknej1vYLckBQ2pAgxZgJN', - 'QmVasycSFzCYhyXrcvTE7mN3d6W78RFnrhzg5cRF6Dp6Zq', - 'QmTmnhjpTBjZdeHwXgT9Dftc3uWMW73qsZpZ5ECrTyiKKZ', - 'QmWDBiyVPyFkzUrEdvy7DSJe1rBQpene1m6quKAtyjBP6a', - 'QmcxxzQZwgG7SE9QbHNvoTiCi6Dhs9rrz9roqvxm2JQA88', - 'Qmd9ThEpXLLHimEzRUWEFrAGLSw5PAHzn2SmwfCnjNLwWt', - 'Qmc7pWw1yxc2ARBWitDMYiyPkWK61NsXXU8oYAQwNAvcx1', - 'QmX9Hgw1rMFUgBBuq8QfZZDzLjN5xCED19fwFdDeDDqwmr', - 'QmconCAyNyaagqKvvfKCbG7Eu8c6vCtkv2ivvxMoFN9YwA', - 'QmWbFmvViy5gx4JdD5sw5YJETet4ZQcXtYgijYnrsnSZ3a', - 'QmP6QiiJwoqkduZMqdd5e5htHZ4aYHCsvEu7WEEUknKYa5', - 'QmefHk8hvBUHsuKugntok5u75Q8i886cnPwsj4LZZB6uWg', - 'QmdrSDK5ByYHxc88hfDu8hQgK5XYFpXSfPorUXdyTbE437', - 'QmZ6ZycjRzYpsjnLm1Lfgk1fXXDdhcYRkyfmqYJZVGwADy', - 'QmSkBxS5yLPjB2VPs89oQRZANsoyodK6s8s52E8GKXr2zt', - 'QmSn8TCPwq3UZ1Z4eyko76CvQo2H2Hyef1NGboDQN22m5i', - 'QmP6CTH5zrKMzZwtjy7VaK9NXiq4Gw53kmuRjUbJjeovoe', - 'QmdwT4yvz9Xf8g3t6irKRoh3Wa7MwRQrcUJckQxyQe1Bc5', - 'QmcwuHH3bD5JExqjDvKqRQ3V5xEVGqs94qPNVDzaCqJa5a', - 'QmRfVduHwn8sXwSoyfgZpxSi8L7EjP4LMp6fmijo9VApDp', - 'Qmc4TGj1Ahbg9HJ9WDXDm2bXsNkT4zRDp8Wdw9wqqdEwuH', - 'QmY8uQiHMWA8ztf2wAurNFW7eiTHQEUiLTQ2vGceMwVqz3', - 'QmXiXbaD12F4mkbUSQcKhWshkPU4oi29cUawZGnPk86VVU', - 'QmZaiAGjvBZBw4suz33s9JQNzY2Kshean2mQQPCa6gKMQe', - 'Qme8bDSdzX7tanPYf672xXW8vPdkLkeSLqLzHJqidRXsYJ', - 'QmRJirjuUKgh2AMyBF4jNquaXHFPBtDJf3gKFC614hX7qu', - 'QmdRoSKSgabcrpekNBPB6T47RBtJnCETYE8ry2a3P37MUe', - 'QmXoqArruHSghrUGW35vVQHPknBG5Cj939iWWHHXU3B616', - 'QmYCxtDuoHLMAFhNpifUsLU9ptAeFKwyxSiSEJhDQLMZtN', - 'QmQZQBw8wgzUsrmVDEejdePK23AEJbk9aUracvxLPyHz2x', - 'QmSsbu7U3i62AQKuYqfisRo5E6nqdMZfHRKWYJgouaXDxD', - 'QmaP4adVQuWyqtN4QCXeYXj4nr19Je4EqsaTG1zM9ywqFS', - 'QmPPsvgfXsiN3wNqdAwHAhQVpw6SZWNpry9Na6R2Xb7zXY', - 'QmR7z6wQmcfZUvRsVK83GRRboyvwZEDQujLwumMY33nAit', - 'QmQXgkgorDLPUyQpFbW8aLUW6jioQjUKamtXw5UuNCttDg', - 'QmcwYBeXt1BPfdSrtSrXFpWctRZ7RDHvmKTttC5hPPTSzG', - 'QmTUexZnw3xPy3YVdUsqJALwTvy2qFax5b3QpJVMvTCJQb', - 'QmNLkYXFUvctpfeeDTZxruZE2f834EUnYMM6JJUeTcUB4J', - 'QmT7544UaTPgKFYMCpPE4unXphNGX71BLZBPKLkxAijSmj', - 'QmTpVR4dqX1QV4fae5pZ1ACtRcANHwEWCLwpMXFmwE95Sm', - 'Qmdfyps5fW8d8wstXMfpvpei2DTmaADBWgmxLT7e7uan4P', - 'QmUSK8byipYoG3H97QpmPrHw9vYrvHygyhkiM81XmaKyxS', - 'QmQUGRvp96LTw5i8Ly9f5LoMvUpeQHCLGNqC88KV74wEHK', - 'Qma693TFLh9Z1MeBFzhPHi6Yk4tmTcZY2jogwJ8cPkU2B4', - 'QmNu8FyMpmkFdbCXGRVG8mKJtMvvCoLP8LNzFsxBQwxQeS', - 'QmWZHE87PKujL1MGLuFgP3D12o5GQxYbvbeTRgr12f1XMu', - 'QmcZJn8gPGd3poS9yuiNJh6iP4cn9uy5fnypky71r4sSSw', - 'QmTwrAF4E9ucpdnrUZFj6EfrQamGv7Qyn7ceSx1DUQYceC', - 'QmexssxU5iTXypgNqrmrQwMDJnTNxyZUxor5wDLnwb5TZp' + "QmPbFkiXNuaQyfwD4W9GcXP7qWaNd6wFd9KCnJir5mes1J", + "QmPVjvbaMxSJRpDxMLYTdUWQbknej1vYLckBQ2pAgxZgJN", + "QmVasycSFzCYhyXrcvTE7mN3d6W78RFnrhzg5cRF6Dp6Zq", + "QmTmnhjpTBjZdeHwXgT9Dftc3uWMW73qsZpZ5ECrTyiKKZ", + "QmWDBiyVPyFkzUrEdvy7DSJe1rBQpene1m6quKAtyjBP6a", + "QmcxxzQZwgG7SE9QbHNvoTiCi6Dhs9rrz9roqvxm2JQA88", + "Qmd9ThEpXLLHimEzRUWEFrAGLSw5PAHzn2SmwfCnjNLwWt", + "Qmc7pWw1yxc2ARBWitDMYiyPkWK61NsXXU8oYAQwNAvcx1", + "QmX9Hgw1rMFUgBBuq8QfZZDzLjN5xCED19fwFdDeDDqwmr", + "QmconCAyNyaagqKvvfKCbG7Eu8c6vCtkv2ivvxMoFN9YwA", + "QmWbFmvViy5gx4JdD5sw5YJETet4ZQcXtYgijYnrsnSZ3a", + "QmP6QiiJwoqkduZMqdd5e5htHZ4aYHCsvEu7WEEUknKYa5", + "QmefHk8hvBUHsuKugntok5u75Q8i886cnPwsj4LZZB6uWg", + "QmdrSDK5ByYHxc88hfDu8hQgK5XYFpXSfPorUXdyTbE437", + "QmZ6ZycjRzYpsjnLm1Lfgk1fXXDdhcYRkyfmqYJZVGwADy", + "QmSkBxS5yLPjB2VPs89oQRZANsoyodK6s8s52E8GKXr2zt", + "QmSn8TCPwq3UZ1Z4eyko76CvQo2H2Hyef1NGboDQN22m5i", + "QmP6CTH5zrKMzZwtjy7VaK9NXiq4Gw53kmuRjUbJjeovoe", + "QmdwT4yvz9Xf8g3t6irKRoh3Wa7MwRQrcUJckQxyQe1Bc5", + "QmcwuHH3bD5JExqjDvKqRQ3V5xEVGqs94qPNVDzaCqJa5a", + "QmRfVduHwn8sXwSoyfgZpxSi8L7EjP4LMp6fmijo9VApDp", + "Qmc4TGj1Ahbg9HJ9WDXDm2bXsNkT4zRDp8Wdw9wqqdEwuH", + "QmY8uQiHMWA8ztf2wAurNFW7eiTHQEUiLTQ2vGceMwVqz3", + "QmXiXbaD12F4mkbUSQcKhWshkPU4oi29cUawZGnPk86VVU", + "QmZaiAGjvBZBw4suz33s9JQNzY2Kshean2mQQPCa6gKMQe", + "Qme8bDSdzX7tanPYf672xXW8vPdkLkeSLqLzHJqidRXsYJ", + "QmRJirjuUKgh2AMyBF4jNquaXHFPBtDJf3gKFC614hX7qu", + "QmdRoSKSgabcrpekNBPB6T47RBtJnCETYE8ry2a3P37MUe", + "QmXoqArruHSghrUGW35vVQHPknBG5Cj939iWWHHXU3B616", + "QmYCxtDuoHLMAFhNpifUsLU9ptAeFKwyxSiSEJhDQLMZtN", + "QmQZQBw8wgzUsrmVDEejdePK23AEJbk9aUracvxLPyHz2x", + "QmSsbu7U3i62AQKuYqfisRo5E6nqdMZfHRKWYJgouaXDxD", + "QmaP4adVQuWyqtN4QCXeYXj4nr19Je4EqsaTG1zM9ywqFS", + "QmPPsvgfXsiN3wNqdAwHAhQVpw6SZWNpry9Na6R2Xb7zXY", + "QmR7z6wQmcfZUvRsVK83GRRboyvwZEDQujLwumMY33nAit", + "QmQXgkgorDLPUyQpFbW8aLUW6jioQjUKamtXw5UuNCttDg", + "QmcwYBeXt1BPfdSrtSrXFpWctRZ7RDHvmKTttC5hPPTSzG", + "QmTUexZnw3xPy3YVdUsqJALwTvy2qFax5b3QpJVMvTCJQb", + "QmNLkYXFUvctpfeeDTZxruZE2f834EUnYMM6JJUeTcUB4J", + "QmT7544UaTPgKFYMCpPE4unXphNGX71BLZBPKLkxAijSmj", + "QmTpVR4dqX1QV4fae5pZ1ACtRcANHwEWCLwpMXFmwE95Sm", + "Qmdfyps5fW8d8wstXMfpvpei2DTmaADBWgmxLT7e7uan4P", + "QmUSK8byipYoG3H97QpmPrHw9vYrvHygyhkiM81XmaKyxS", + "QmQUGRvp96LTw5i8Ly9f5LoMvUpeQHCLGNqC88KV74wEHK", + "Qma693TFLh9Z1MeBFzhPHi6Yk4tmTcZY2jogwJ8cPkU2B4", + "QmNu8FyMpmkFdbCXGRVG8mKJtMvvCoLP8LNzFsxBQwxQeS", + "QmWZHE87PKujL1MGLuFgP3D12o5GQxYbvbeTRgr12f1XMu", + "QmcZJn8gPGd3poS9yuiNJh6iP4cn9uy5fnypky71r4sSSw", + "QmTwrAF4E9ucpdnrUZFj6EfrQamGv7Qyn7ceSx1DUQYceC", + "QmexssxU5iTXypgNqrmrQwMDJnTNxyZUxor5wDLnwb5TZp", ]; diff --git a/src/lib/translations/index.js b/src/lib/translations/index.js index 5f4f1754..a07a6dbf 100644 --- a/src/lib/translations/index.js +++ b/src/lib/translations/index.js @@ -1,68 +1,71 @@ -import i18n from 'sveltekit-i18n'; -import lang from './lang.json'; +import i18n from "sveltekit-i18n"; +import lang from "./lang.json"; // setup loaders & translations from lang.json data function createLocaleLoader(localeCode) { - return { - locale: localeCode, - key: '', - loader: async () => (await import(`../../locales/${localeCode}.json`)).default - }; + return { + locale: localeCode, + key: "", + loader: async () => + (await import(`../../locales/${localeCode}.json`)).default, + }; } const availableLocales = Object.keys(lang); const translations = {}; for (let i = 0; i < availableLocales.length; i++) { - translations[availableLocales[i]] = { lang }; + translations[availableLocales[i]] = { lang }; } const loaders = availableLocales.map(createLocaleLoader); const config = { - initLocale: 'en', - fallbackLocale: 'en', - translations, - loaders: [ - { - locale: 'en', - key: '', - loader: async () => (await import('../../locales/en.json')).default - }, - { - locale: 'es', - key: '', - loader: async () => (await import('../../locales/es.json')).default - }, - { - locale: 'fr', - key: '', - loader: async () => (await import('../../locales/fr.json')).default - }, - { - locale: 'pt', - key: '', - loader: async () => (await import('../../locales/pt.json')).default - }, - { - locale: 'de', - key: '', - loader: async () => (await import('../../locales/de.json')).default - }, - { - locale: 'zh', - key: '', - loader: async () => (await import('../../locales/zh.json')).default - }, - { - locale: 'fa', - key: '', - loader: async () => (await import('../../locales/fa.json')).default - }, - { - locale: 'el', - key: '', - loader: async () => (await import('../../locales/el.json')).default - } - ] + initLocale: "en", + fallbackLocale: "en", + translations, + loaders: [ + { + locale: "en", + key: "", + loader: async () => (await import("../../locales/en.json")).default, + }, + { + locale: "es", + key: "", + loader: async () => (await import("../../locales/es.json")).default, + }, + { + locale: "fr", + key: "", + loader: async () => (await import("../../locales/fr.json")).default, + }, + { + locale: "pt", + key: "", + loader: async () => (await import("../../locales/pt.json")).default, + }, + { + locale: "de", + key: "", + loader: async () => (await import("../../locales/de.json")).default, + }, + { + locale: "zh", + key: "", + loader: async () => (await import("../../locales/zh.json")).default, + }, + { + locale: "fa", + key: "", + loader: async () => (await import("../../locales/fa.json")).default, + }, + { + locale: "el", + key: "", + loader: async () => (await import("../../locales/el.json")).default, + }, + ], }; -export const { t, loading, locales, locale, loadTranslations } = new i18n(config); +export const { t, loading, locales, locale, loadTranslations } = new i18n( + config +); diff --git a/src/lib/translations/lang.json b/src/lib/translations/lang.json index 0acc1de6..d18a67e3 100644 --- a/src/lib/translations/lang.json +++ b/src/lib/translations/lang.json @@ -1,10 +1,10 @@ { - "en": "English", - "fr": "Français", - "es": "Español", - "de": "Deutsch", - "pt": "Português", - "zh": "中国人", - "fa": "فارسی ", - "el": "Ελληνικά" + "en": "English", + "fr": "Français", + "es": "Español", + "de": "Deutsch", + "pt": "Português", + "zh": "中国人", + "fa": "فارسی ", + "el": "Ελληνικά" } diff --git a/src/lib/upload.js b/src/lib/upload.js index 92f5290f..552e4a7a 100644 --- a/src/lib/upload.js +++ b/src/lib/upload.js @@ -1,19 +1,19 @@ export const upload = async (file, type, progress, token) => { - let url = `/api/upload/${type}`; - let formData = new FormData(); - formData.append('file', file); + let url = `/api/upload/${type}`; + let formData = new FormData(); + formData.append("file", file); - return new Promise((resolve, reject) => { - let ajax = new XMLHttpRequest(); - ajax.addEventListener('load', () => { - if (ajax.readyState === ajax.DONE) { - if (ajax.status === 200) resolve(ajax.response); - else reject(new Error(`Upload failed: ${ajax.response}`)); - } - }); - ajax.upload.addEventListener('progress', progress, false); - ajax.open('POST', url); - // ajax.setRequestHeader('Authorization', `Bearer ${token}`); - ajax.send(formData); - }); + return new Promise((resolve, reject) => { + let ajax = new XMLHttpRequest(); + ajax.addEventListener("load", () => { + if (ajax.readyState === ajax.DONE) { + if (ajax.status === 200) resolve(ajax.response); + else reject(new Error(`Upload failed: ${ajax.response}`)); + } + }); + ajax.upload.addEventListener("progress", progress, false); + ajax.open("POST", url); + // ajax.setRequestHeader('Authorization', `Bearer ${token}`); + ajax.send(formData); + }); }; diff --git a/src/lib/utils.js b/src/lib/utils.js index 9b3e5592..c0df81ae 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -1,266 +1,282 @@ -import { browser } from '$app/environment'; -import { toast } from '@zerodevx/svelte-toast'; -import { goto } from '$app/navigation'; -import { PUBLIC_COINOS_URL } from '$env/static/public'; -import { page } from '$app/stores'; -import { get as getStore } from 'svelte/store'; +import { browser } from "$app/environment"; +import { toast } from "@zerodevx/svelte-toast"; +import { goto } from "$app/navigation"; +import { PUBLIC_COINOS_URL } from "$env/static/public"; +import { page } from "$app/stores"; +import { get as getStore } from "svelte/store"; export function scroll(section) { - if (getStore(page).url.pathname !== '/') goto('/'); - setTimeout(() => section.scrollIntoView({ behavior: 'smooth' }), 500); + if (getStore(page).url.pathname !== "/") goto("/"); + setTimeout(() => section.scrollIntoView({ behavior: "smooth" }), 500); } -let base = browser ? '' : PUBLIC_COINOS_URL; +let base = browser ? "" : PUBLIC_COINOS_URL; -export let punk = (k) => Math.floor((parseInt(k.slice(-2), 16) / 256) * 64) + 1 + '.webp'; +export let punk = (k) => + Math.floor((parseInt(k.slice(-2), 16) / 256) * 64) + 1 + ".webp"; export let g = (url, fetch, headers) => - fetch(base + url, { headers }) - .then((r) => r.text()) - .then((body) => { - try { - return JSON.parse(body); - } catch (e) { - throw new Error(body); - } - }); + fetch(base + url, { headers }) + .then((r) => r.text()) + .then((body) => { + try { + return JSON.parse(body); + } catch (e) { + throw new Error(body); + } + }); export let get = (url, headers = {}) => { - return fetch(base + url, { headers }) - .then(async (r) => { - if (r.ok) return r.text(); - throw new Error(await r.text()); - }) - .then((body) => { - try { - return JSON.parse(body); - } catch (e) { - return body; - } - }); -} + return fetch(base + url, { headers }) + .then(async (r) => { + if (r.ok) return r.text(); + throw new Error(await r.text()); + }) + .then((body) => { + try { + return JSON.parse(body); + } catch (e) { + return body; + } + }); +}; export let post = (url, body, headers) => { - headers = { ...headers, 'content-type': 'application/json', accept: 'application/json' }; - return fetch(base + url, { method: 'POST', body: JSON.stringify(body), headers }) - .then(async (r) => { - if (r.ok) return r.text(); - let text = await r.text(); + headers = { + ...headers, + "content-type": "application/json", + accept: "application/json", + }; + return fetch(base + url, { + method: "POST", + body: JSON.stringify(body), + headers, + }) + .then(async (r) => { + if (r.ok) return r.text(); + let text = await r.text(); - let message; - try { - ({ message } = JSON.parse(text)); - } catch (e) {} + let message; + try { + ({ message } = JSON.parse(text)); + } catch (e) {} - if (message) throw new Error(message); - throw new Error(text); - }) - .then((body) => { - try { - body = JSON.parse(body); - } catch (e) { - throw new Error(body); - } + if (message) throw new Error(message); + throw new Error(text); + }) + .then((body) => { + try { + body = JSON.parse(body); + } catch (e) { + throw new Error(body); + } - if (body.error instanceof Error) throw body.error; - if (body instanceof Error) throw body; - if (body.name === 'Error') throw new Error(body.message); + if (body.error instanceof Error) throw body.error; + if (body instanceof Error) throw body; + if (body.name === "Error") throw new Error(body.message); - return body; - }); + return body; + }); }; export let copy = (text) => { - navigator.clipboard.writeText(text); - success('Copied!'); + navigator.clipboard.writeText(text); + success("Copied!"); }; export let copyNoNewlines = (text) => { - let stripped = text.replace(/\n/g, ' ').replace(/\s+/g, ' '); - navigator.clipboard.writeText(stripped); - success('Copied!'); + let stripped = text.replace(/\n/g, " ").replace(/\s+/g, " "); + navigator.clipboard.writeText(stripped); + success("Copied!"); }; export function reverseFormat(val, locale) { - let parts = new Intl.NumberFormat(locale).formatToParts(1111.1); - let group = parts.find((part) => part.type === 'group').value; - let decimal = parts.find((part) => part.type === 'decimal').value; - let reversedVal = val.replace(new RegExp('\\' + group, 'g'), ''); - reversedVal = reversedVal.replace(new RegExp('\\' + decimal, 'g'), '.'); - return Number.isNaN(reversedVal) ? 0 : +reversedVal; + let parts = new Intl.NumberFormat(locale).formatToParts(1111.1); + let group = parts.find((part) => part.type === "group").value; + let decimal = parts.find((part) => part.type === "decimal").value; + let reversedVal = val.replace(new RegExp("\\" + group, "g"), ""); + reversedVal = reversedVal.replace(new RegExp("\\" + decimal, "g"), "."); + return Number.isNaN(reversedVal) ? 0 : +reversedVal; } export let protectedRoutes = [/customers/, /settings/, /payments/]; export let success = (m) => { - toast.pop(); - toast.push(m, { - theme: { - '--toastBarBackground': '#F5F7FA' - } - }); + toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "#F5F7FA", + }, + }); }; export let warning = (m) => { - toast.pop(); - toast.push(m, { - theme: { - '--toastBarBackground': '#FFCE22' - } - }); + toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "#FFCE22", + }, + }); }; export let fail = (m) => { - toast.pop(); - toast.push(m, { - theme: { - '--toastBarBackground': '#E93535' - } - }); + toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "#E93535", + }, + }); }; export let info = (m) => { - toast.pop(); - toast.push(m, { - theme: { - '--toastBarBackground': 'white' - } - }); + toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "white", + }, + }); }; export let login = async (user, cookies, ip) => { - let maxAge = 380 * 24 * 60 * 60; + let maxAge = 380 * 24 * 60 * 60; - let res = await fetch(base + '/login', { - method: 'POST', - body: JSON.stringify(user), - headers: { - 'content-type': 'application/json', - accept: 'application/json', - 'cf-connecting-ip': ip - } - }); - if (res.status === 401) { - let text = await res.text(); - if (text.startsWith('2fa')) throw new Error('2fa'); - } + let res = await fetch(base + "/login", { + method: "POST", + body: JSON.stringify(user), + headers: { + "content-type": "application/json", + accept: "application/json", + "cf-connecting-ip": ip, + }, + }); + if (res.status === 401) { + let text = await res.text(); + if (text.startsWith("2fa")) throw new Error("2fa"); + } - let { token } = await res.json(); - if (!token) throw new Error('Login failed'); + let { token } = await res.json(); + if (!token) throw new Error("Login failed"); - let expires = new Date(); - expires.setSeconds(expires.getSeconds() + maxAge); + let expires = new Date(); + expires.setSeconds(expires.getSeconds() + maxAge); - let opts = { path: '/', expires }; - cookies.set('username', user.username, opts); - cookies.set('token', token, opts); + let opts = { path: "/", expires }; + cookies.set("username", user.username, opts); + cookies.set("token", token, opts); }; -export let auth = (cookies) => ({ authorization: `Bearer ${cookies.get('token')}` }); +export let auth = (cookies) => ({ + authorization: `Bearer ${cookies.get("token")}`, +}); export let fiat = (amount, rate) => (amount * rate) / sats; export let fd = async (req) => { - let obj = Object.fromEntries(await req.formData()); - for (let k in obj) - (obj[k] === 'undefined' && (obj[k] = undefined)) || (obj[k] === 'false' && (obj[k] = false)); - return obj; + let obj = Object.fromEntries(await req.formData()); + for (let k in obj) + (obj[k] === "undefined" && (obj[k] = undefined)) || + (obj[k] === "false" && (obj[k] = false)); + return obj; }; export let f = (s, currency) => - new Intl.NumberFormat('en-US', { - style: 'currency', - currency - }) - .format(s) - .replace('CA', ''); + new Intl.NumberFormat("en-US", { + style: "currency", + currency, + }) + .format(s) + .replace("CA", ""); -export let s = (s) => new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(s); +export let s = (s) => + new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 }).format(s); export let sat = (s) => { - s = Math.abs(s); - let p = Math.floor(Math.log(s) / Math.LN10 + 0.000000001); - let d = Math.floor((p + 1) / 3); + s = Math.abs(s); + let p = Math.floor(Math.log(s) / Math.LN10 + 0.000000001); + let d = Math.floor((p + 1) / 3); - return ( - '⚡️' + - (parseInt(s) > 0 - ? new Intl.NumberFormat('en-US', { maximumFractionDigits: 2 }).format(s / Math.pow(1000, d)) + - ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z'][d] - : 0 - ).toString() - ); + return ( + "⚡️" + + (parseInt(s) > 0 + ? new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format( + s / Math.pow(1000, d) + ) + ["", "K", "M", "G", "T", "P", "E", "Z"][d] + : 0 + ).toString() + ); }; export let sats = 100000000; -export let back = () => browser && (history.length ? history.go(-1) : goto('/')); -export let focus = (el) => browser && screen.width > 1280 && setTimeout(() => el.focus(), 1); +export let back = () => + browser && (history.length ? history.go(-1) : goto("/")); +export let focus = (el) => + browser && screen.width > 1280 && setTimeout(() => el.focus(), 1); export let sleep = (n) => new Promise((r) => setTimeout(r, n)); export let wait = async (f, n = 100, s = 300) => { - let i = 0; - while (!(await f()) && i < s) (await sleep(n)) && i++; - if (i >= s) throw new Error('timeout'); - return f(); + let i = 0; + while (!(await f()) && i < s) (await sleep(n)) && i++; + if (i >= s) throw new Error("timeout"); + return f(); }; export let stretch = async (password, salt) => - crypto.subtle.deriveKey( - { - name: 'PBKDF2', - salt, - iterations: 100000, - hash: 'SHA-256' - }, - await crypto.subtle.importKey( - 'raw', - new TextEncoder().encode(password), - { name: 'PBKDF2' }, - false, - ['deriveBits', 'deriveKey'] - ), - { name: 'AES-GCM', length: 256 }, - true, - ['encrypt', 'decrypt'] - ); + crypto.subtle.deriveKey( + { + name: "PBKDF2", + salt, + iterations: 100000, + hash: "SHA-256", + }, + await crypto.subtle.importKey( + "raw", + new TextEncoder().encode(password), + { name: "PBKDF2" }, + false, + ["deriveBits", "deriveKey"] + ), + { name: "AES-GCM", length: 256 }, + true, + ["encrypt", "decrypt"] + ); function get_bigrams(string) { - var s = string.toLowerCase(); - var v = s.split(''); - for (var i = 0; i < v.length; i++) { - v[i] = s.slice(i, i + 2); - } - return v; + var s = string.toLowerCase(); + var v = s.split(""); + for (var i = 0; i < v.length; i++) { + v[i] = s.slice(i, i + 2); + } + return v; } export function ss(str1, str2) { - if (str1.length > 0 && str2.length > 0) { - var pairs1 = get_bigrams(str1); - var pairs2 = get_bigrams(str2); - var union = pairs1.length + pairs2.length; - var hits = 0; - for (var x = 0; x < pairs1.length; x++) { - for (var y = 0; y < pairs2.length; y++) { - if (pairs1[x] == pairs2[y]) hit_count++; - } - } - if (hits > 0) return (2.0 * hits) / union; - } + if (str1.length > 0 && str2.length > 0) { + var pairs1 = get_bigrams(str1); + var pairs2 = get_bigrams(str2); + var union = pairs1.length + pairs2.length; + var hits = 0; + for (var x = 0; x < pairs1.length; x++) { + for (var y = 0; y < pairs2.length; y++) { + if (pairs1[x] == pairs2[y]) hit_count++; + } + } + if (hits > 0) return (2.0 * hits) / union; + } - return 0.0; + return 0.0; } export let types = { - bitcoin: 'bitcoin', - lightning: 'lightning', - internal: 'internal', - fund: 'fund', - classic: 'classic' + bitcoin: "bitcoin", + lightning: "lightning", + internal: "internal", + fund: "fund", + classic: "classic", }; -export let ease = (t) => (t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t); - - export function shuffleArray(array) { - for (let i = array.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [array[i], array[j]] = [array[j], array[i]]; - } - } +export let ease = (t) => + t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t; +export function shuffleArray(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } +} |
