diff options
| author | Adam Soltys <[email protected]> | 2024-10-18 09:08:07 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-10-18 09:09:14 -0700 |
| commit | 002cd9134d2e23bec34f838f6d6fefba41f2d530 (patch) | |
| tree | 92fa0e0ab54ce1a715d25f458de8b8ed8cc70bd5 /src/lib | |
| parent | f6bfe889d91bc6e36b0300d7b618f10158efe176 (diff) | |
| download | coinos-ui-002cd9134d2e23bec34f838f6d6fefba41f2d530.tar.gz coinos-ui-002cd9134d2e23bec34f838f6d6fefba41f2d530.zip | |
biome format
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/handler.ts | 16 | ||||
| -rw-r--r-- | src/lib/invoice.ts | 48 | ||||
| -rw-r--r-- | src/lib/nostr.ts | 192 | ||||
| -rw-r--r-- | src/lib/parse.ts | 118 | ||||
| -rw-r--r-- | src/lib/punks.ts | 128 | ||||
| -rw-r--r-- | src/lib/samples.ts | 30 | ||||
| -rw-r--r-- | src/lib/socket.ts | 101 | ||||
| -rw-r--r-- | src/lib/store.ts | 54 | ||||
| -rw-r--r-- | src/lib/ticket.ts | 44 | ||||
| -rw-r--r-- | src/lib/tickets.ts | 100 | ||||
| -rw-r--r-- | src/lib/types.ts | 24 | ||||
| -rw-r--r-- | src/lib/upload.ts | 30 | ||||
| -rw-r--r-- | src/lib/utils.ts | 480 |
13 files changed, 686 insertions, 679 deletions
diff --git a/src/lib/handler.ts b/src/lib/handler.ts index 559761f0..baca442d 100644 --- a/src/lib/handler.ts +++ b/src/lib/handler.ts @@ -2,12 +2,12 @@ import { goto } from "$app/navigation"; import { applyAction } from "$app/forms"; export default (toggle) => () => { - toggle(); - return async ({ result }) => { - if (result.type === "redirect") { - goto(result.location); - } else { - await applyAction(result); - } - }; + toggle(); + return async ({ result }) => { + if (result.type === "redirect") { + goto(result.location); + } else { + await applyAction(result); + } + }; }; diff --git a/src/lib/invoice.ts b/src/lib/invoice.ts index fa2f7786..fec845f9 100644 --- a/src/lib/invoice.ts +++ b/src/lib/invoice.ts @@ -2,34 +2,34 @@ import { auth, get, post } from "$lib/utils"; import { redirect } from "@sveltejs/kit"; export default async ({ cookies, request }) => { - let aid = cookies.get("aid"); - let form = await request.formData(); + let aid = cookies.get("aid"); + let form = await request.formData(); - let rates = await get("/rates"); - let amount = parseInt(form.get("amount")); + let rates = await get("/rates"); + let amount = parseInt(form.get("amount")); - let invoice = { - aid, - amount, - items: JSON.parse(form.get("items")), - memo: form.get("memo"), - memoPrompt: form.get("memoPrompt"), - tip: parseInt(form.get("tip")) || 0, - type: form.get("type"), - prompt: form.get("prompt") === "true", - rate: parseFloat(form.get("rate")) || rates[form.get("currency")], - id: undefined, - }; + let invoice = { + aid, + amount, + items: JSON.parse(form.get("items")), + memo: form.get("memo"), + memoPrompt: form.get("memoPrompt"), + tip: parseInt(form.get("tip")) || 0, + type: form.get("type"), + prompt: form.get("prompt") === "true", + rate: parseFloat(form.get("rate")) || rates[form.get("currency")], + id: undefined, + }; - 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 (invoice.prompt && invoice.tip === null) - redirect(307, `/invoice/${id}/tip`); + if (invoice.prompt && invoice.tip === null) + redirect(307, `/invoice/${id}/tip`); - if (invoice.memoPrompt && !invoice.memo) { - redirect(307, `/invoice/${id}/memo`); - } else redirect(307, `/invoice/${id}`); + if (invoice.memoPrompt && !invoice.memo) { + redirect(307, `/invoice/${id}/memo`); + } else redirect(307, `/invoice/${id}`); }; diff --git a/src/lib/nostr.ts b/src/lib/nostr.ts index a9926ba1..a00a28f9 100644 --- a/src/lib/nostr.ts +++ b/src/lib/nostr.ts @@ -5,16 +5,16 @@ import { Buffer } from "buffer"; import { wait, post, stretch } from "$lib/utils"; import { decrypted, password as pw, passwordPrompt, pin } from "$lib/store"; import { - getPublicKey, - finalizeEvent, - nip04, - nip19, - type EventTemplate, + getPublicKey, + finalizeEvent, + nip04, + nip19, + type EventTemplate, } from "nostr-tools"; import { - encrypt as nip49encrypt, - decrypt as nip49decrypt, + encrypt as nip49encrypt, + decrypt as nip49decrypt, } from "nostr-tools/nip49"; import { mnemonicToEntropy, entropyToMnemonic } from "@scure/bip39"; @@ -24,154 +24,154 @@ import { wordlist } from "@scure/bip39/wordlists/english"; import { generateSeedWords, privateKeyFromSeedWords } from "nostr-tools/nip06"; type User = { - [key: string]: any; + [key: string]: any; }; type EncryptParams = { - message: string; - recipient: string; - user: User; + message: string; + recipient: string; + user: User; }; const { encode, decode, toWords, fromWords } = bech32m; export let generate = async (user: any) => { - let p = get(pin); - if (p && p.length !== 6) return; + let p = get(pin); + if (p && p.length !== 6) return; - 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(await getPassword(), salt), - mnemonicToEntropy(mnemonic, wordlist) - ) - ); + let bytes = new Uint8Array( + await crypto.subtle.encrypt( + { name: "AES-GCM", iv: new Uint8Array(16) }, + await stretch(await getPassword(), salt), + mnemonicToEntropy(mnemonic, wordlist), + ), + ); - user.pubkey = getPublicKey(hexToUint8Array(sk)); - user.cipher = encode("en", toWords(bytes), 180); - user.salt = Buffer.from(salt).toString("hex"); + user.pubkey = getPublicKey(hexToUint8Array(sk)); + user.cipher = encode("en", toWords(bytes), 180); + user.salt = Buffer.from(salt).toString("hex"); }; export let encrypt = async ({ message, recipient, user }: EncryptParams) => { - let sk = await getPrivateKey(user); - return nip04.encrypt(sk, recipient, message); + let sk = await getPrivateKey(user); + return nip04.encrypt(sk, 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); + } }; export let getPrivateKey = async (user: User): Promise<Uint8Array> => { - let k; - if (browser) { - k = localStorage.getItem("nsec"); - if (k) { - return nip19.decode(k).data as Uint8Array; - } - } + let k; + if (browser) { + k = localStorage.getItem("nsec"); + if (k) { + return nip19.decode(k).data as Uint8Array; + } + } - let { nsec } = user; + let { nsec } = user; - if (nsec) { - k = nip49decrypt(nsec, await getPassword()); - } else k = hexToUint8Array(privateKeyFromSeedWords(await getMnemonic(user))); + if (nsec) { + k = nip49decrypt(nsec, await getPassword()); + } else k = hexToUint8Array(privateKeyFromSeedWords(await getMnemonic(user))); - localStorage.setItem("nsec", nip19.nsecEncode(k)); - return k; + localStorage.setItem("nsec", nip19.nsecEncode(k)); + return k; }; export let getMnemonic = async (user: User) => { - let { cipher, salt } = user; - let entropy; + let { cipher, salt } = user; + let entropy; - entropy = new Uint8Array( - await crypto.subtle.decrypt( - { name: "AES-GCM", iv: new Uint8Array(16) }, - await stretch(await getPassword(), 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(await getPassword(), Buffer.from(salt, "hex")), + Uint8Array.from(fromWords(decode(cipher, 180).words)), + ), + ); - return entropyToMnemonic(entropy, wordlist); + return entropyToMnemonic(entropy, wordlist); }; let decodeNsec = (nsec: string): Uint8Array => { - let { type, data } = nip19.decode(nsec); - if (type === "nsec" && data instanceof Uint8Array) return data; - else throw new Error("invalid nsec"); + let { type, data } = nip19.decode(nsec); + if (type === "nsec" && data instanceof Uint8Array) return data; + else throw new Error("invalid nsec"); }; export let getNsec = async (user: User) => { - return nip19.nsecEncode(await getPrivateKey(user)); + return nip19.nsecEncode(await getPrivateKey(user)); }; export let setNsec = async (user: User, nsec: string) => { - user.pubkey = getPublicKey(decodeNsec(nsec)); - user.nsec = await encryptNsec(nsec); + user.pubkey = getPublicKey(decodeNsec(nsec)); + user.nsec = await encryptNsec(nsec); }; export let encryptNsec = async (nsec: string) => { - let d = decodeNsec(nsec); - return nip49encrypt(d, await getPassword()); + let d = decodeNsec(nsec); + return nip49encrypt(d, await getPassword()); }; type SignParams = { - event: EventTemplate; - user: User; + event: EventTemplate; + user: User; }; export let sign = async ({ event, user }: SignParams) => { - event = finalizeEvent(event, await getPrivateKey(user)); + event = finalizeEvent(event, await getPrivateKey(user)); }; export let send = (event: EventTemplate) => { - return post("/events", { event }); + return post("/events", { event }); }; let getPassword = async (): Promise<string> => { - if (!get(pw)) passwordPrompt.set(true); - await wait(() => !!get(pw)); - return get(pw) || ""; + if (!get(pw)) passwordPrompt.set(true); + await wait(() => !!get(pw)); + return get(pw) || ""; }; export let reEncryptEntropy = async (user: User, newPassword: string) => { - let { cipher, salt } = user; + let { cipher, salt } = user; - let entropy = await crypto.subtle.decrypt( - { name: "AES-GCM", iv: new Uint8Array(16) }, - await stretch(await getPassword(), hexToUint8Array(salt)), - Uint8Array.from(fromWords(decode(cipher, 180).words)) - ); + let entropy = await crypto.subtle.decrypt( + { name: "AES-GCM", iv: new Uint8Array(16) }, + await stretch(await getPassword(), hexToUint8Array(salt)), + Uint8Array.from(fromWords(decode(cipher, 180).words)), + ); - let bytes = new Uint8Array( - await crypto.subtle.encrypt( - { name: "AES-GCM", iv: new Uint8Array(16) }, - await stretch(newPassword, hexToUint8Array(salt)), - entropy - ) - ); + let bytes = new Uint8Array( + await crypto.subtle.encrypt( + { name: "AES-GCM", iv: new Uint8Array(16) }, + await stretch(newPassword, hexToUint8Array(salt)), + entropy, + ), + ); - return encode("en", toWords(bytes), 180); + return encode("en", toWords(bytes), 180); }; diff --git a/src/lib/parse.ts b/src/lib/parse.ts index 0ab3e809..fcce7e1e 100644 --- a/src/lib/parse.ts +++ b/src/lib/parse.ts @@ -1,80 +1,80 @@ +import { PUBLIC_DOMAIN } from "$env/static/public"; import { get, isLiquid, post } from "$lib/utils"; +import { redirect } from "@sveltejs/kit"; import bip21 from "bip21"; import { validate } from "bitcoin-address-validation"; -import { PUBLIC_DOMAIN } from "$env/static/public"; -import { redirect } from "@sveltejs/kit"; export default async (t, host) => { - if (!t) return; + if (!t) return; - if (t.startsWith("http")) redirect(307, t); - if (t.startsWith(host)) redirect(307, `http://${t}`); + if (t.startsWith("http")) redirect(307, t); + if (t.startsWith(host)) redirect(307, `http://${t}`); - let amount, user; + let amount, user; - t = t.trim(); - t.toLowerCase().startsWith("bitcoin:") && - ({ - address: t, - options: { amount }, - } = bip21.decode(t)); + t = t.trim(); + t.toLowerCase().startsWith("bitcoin:") && + ({ + address: t, + options: { amount }, + } = bip21.decode(t)); - if (t.startsWith("lightning:")) t = t.replace("lightning:", ""); - if (t.endsWith(`@${PUBLIC_DOMAIN}`)) t = t.split("@")[0]; - if (t.includes("@") && t.includes(".")) { - try { - t = await get(`/encode?address=${t}`); - } catch (e) {} - } + if (t.startsWith("lightning:")) t = t.replace("lightning:", ""); + if (t.endsWith(`@${PUBLIC_DOMAIN}`)) t = t.split("@")[0]; + if (t.includes("@") && t.includes(".")) { + try { + t = await get(`/encode?address=${t}`); + } catch (e) {} + } - if (t.includes("/fund")) redirect(307, t.substring(t.indexOf("/fund"))); + if (t.includes("/fund")) redirect(307, t.substring(t.indexOf("/fund"))); - // lightning - if (t.toLowerCase().startsWith("lightning:")) - t = t.toLowerCase().replace("lightning:", ""); - if (t.toLowerCase().startsWith("lnurl")) redirect(307, `/ln/${t}`); - if (t.includes(":")) t = t.split(":")[1]; + // lightning + if (t.toLowerCase().startsWith("lightning:")) + t = t.toLowerCase().replace("lightning:", ""); + if (t.toLowerCase().startsWith("lnurl")) redirect(307, `/ln/${t}`); + if (t.includes(":")) t = t.split(":")[1]; - if (t.toLowerCase().startsWith("ln")) { - try { - await get(`/invoice/${t}`); - } catch (e) { - redirect(307, `/send/lightning/${t}`); - } - } + if (t.toLowerCase().startsWith("ln")) { + try { + await get(`/invoice/${t}`); + } catch (e) { + redirect(307, `/send/lightning/${t}`); + } + } - // bitcoin - if (validate(t) || isLiquid(t)) { - let r = `/send/bitcoin/${t}`; - if (amount) r += "/" + amount; - redirect(307, r); - } + // bitcoin + if (validate(t) || isLiquid(t)) { + let r = `/send/bitcoin/${t}`; + if (amount) r += "/" + amount; + redirect(307, r); + } - if (t.startsWith("cashu")) { - let { id } = await post("/cash", { token: t }); - redirect(307, `/ecash/${id}`); - } + if (t.startsWith("cashu")) { + const { id } = await post("/cash", { token: t }); + redirect(307, `/ecash/${id}`); + } - // user - try { - user = await get(`/users/${t.split("/")[0]}`); - if (user.anon) user = null; - } catch (e) {} + // user + try { + user = await get(`/users/${t.split("/")[0]}`); + if (user.anon) user = null; + } catch (e) {} - if (user) redirect(307, `/pay/${t}`); + if (user) redirect(307, `/pay/${t}`); - let fund; - try { - fund = await get(`/fund/${t}`); - } catch (e) {} + let fund; + try { + fund = await get(`/fund/${t}`); + } catch (e) {} - if (fund) redirect(307, `/send/fund/${t}`); + if (fund) redirect(307, `/send/fund/${t}`); - // invoice - let invoice; - try { - invoice = await get(`/invoice/${t}`); - } catch (e) {} + // invoice + let invoice; + try { + invoice = await get(`/invoice/${t}`); + } catch (e) {} - if (invoice) redirect(307, `/send/invoice/${invoice.id}`); + if (invoice) redirect(307, `/send/invoice/${invoice.id}`); }; diff --git a/src/lib/punks.ts b/src/lib/punks.ts index e5551062..8b7b53df 100644 --- a/src/lib/punks.ts +++ b/src/lib/punks.ts @@ -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.ts b/src/lib/samples.ts index 17e4f4c8..1cd74409 100644 --- a/src/lib/samples.ts +++ b/src/lib/samples.ts @@ -1,48 +1,48 @@ import { PUBLIC_DOMAIN, PUBLIC_COINOS_URL } from "$env/static/public"; let api = PUBLIC_DOMAIN.includes("localhost") - ? `${PUBLIC_COINOS_URL}` - : `https://${PUBLIC_DOMAIN}/api`; + ? `${PUBLIC_COINOS_URL}` + : `https://${PUBLIC_DOMAIN}/api`; export default { - register: `curl "${api}/register" -H "content-type: application/json" -d '{ + register: `curl "${api}/register" -H "content-type: application/json" -d '{ "user": { "username": "demo", "password": "hunter2" } }'`, - login: `curl "${api}/login" -H "content-type: application/json" -d '{ + login: `curl "${api}/login" -H "content-type: application/json" -d '{ "username": "demo", "password": "hunter2" }'`, - payments: `curl "${api}/payments" + payments: `curl "${api}/payments" -H "content-type: application/json" -H "Authorization: Bearer $token" `, - lightning: `curl "${api}/payments" + lightning: `curl "${api}/payments" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ "payreq": "lnbc1pj94d8fsp5n77k340ps4m9jn7kp8he8yynpddvurv6mcsrrqpnq5l2jxdxzlwqpp5m96pqhc5nrlk8cqsu9ufdxxa43sarp8vwf9egvm2pg9nl0zu9r8qdq2vdhkjmn0wvxqztgcqpjrzjqwhmav82kntsppmkp8jp4vg4h9nns78tsy8mg7ve4lq5txrkp0h56zlarvqqdtcqqsqqqqqqqqqqp6cq9q9qyysgqzxlypywzphyujm3ga5j5csfcmqvlnae0fgnvymkaaw94eeg7py5rqzysyjkr3ev2snq63qpsc69vf54adkd0szvmvwt5cuadjnuy95sq4xfa40" }'`, - bitcoin: `curl "${api}/bitcoin/send" + bitcoin: `curl "${api}/bitcoin/send" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ "amount": 5000, "address": "bc1q3unh97w4rmelflrm2hvdwz37d8kray3vn4d5ca" }'`, - internal: `curl "${api}/send" + internal: `curl "${api}/send" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ "amount": 5000, "username": "alice" }'`, - rates: `curl "${api}/rates" + rates: `curl "${api}/rates" -H "content-type: application/json" }'`, - lightningInvoice: `curl "${api}/invoice" + lightningInvoice: `curl "${api}/invoice" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ @@ -51,7 +51,7 @@ export default { "type": "lightning" } }'`, - bitcoinAddress: `curl "${api}/invoice" + bitcoinAddress: `curl "${api}/invoice" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ @@ -60,7 +60,7 @@ export default { "type": "bitcoin" } }'`, - webhook: `curl "${api}/invoice" + webhook: `curl "${api}/invoice" -H "content-type: application/json" -H "Authorization: Bearer $token" -d '{ @@ -70,9 +70,9 @@ export default { "secret": "webhooksecret" } }'`, - fetchInvoice: `curl "${api}/invoice/bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj" + fetchInvoice: `curl "${api}/invoice/bc1qmhfk9stzffhd9umzmld92vff7zg3mdlh7rvvaj" -H "content-type: application/json"'`, - invoiceResponse: `{ + invoiceResponse: `{ "amount":3141 "tip":0 "type":"bitcoin" @@ -85,5 +85,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.ts b/src/lib/socket.ts index 26ab543c..bbedd3ed 100644 --- a/src/lib/socket.ts +++ b/src/lib/socket.ts @@ -11,44 +11,44 @@ let token; export const auth = () => token && send("login", token); export const send = async (type, data) => { - try { - await wait(() => socket && socket.readyState === 1, 100, 10); - } catch (e: any) { - if (e.message === "timeout") reconnectToWebsocket(); - } + try { + await wait(() => socket && socket.readyState === 1, 100, 10); + } catch (e: any) { + if (e.message === "timeout") reconnectToWebsocket(); + } - await wait(() => socket.readyState === 1, 100, 10); - socket.send(JSON.stringify({ type, data })); + await wait(() => socket.readyState === 1, 100, 10); + socket.send(JSON.stringify({ type, data })); }; export const messages = (data) => ({ - id() { - last.set(Date.now()); - }, - invoice() { - invoice.set(data); - }, - event() { - event.set(data); - }, + id() { + last.set(Date.now()); + }, + invoice() { + invoice.set(data); + }, + event() { + event.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; @@ -57,41 +57,44 @@ 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(); } async function onWebsocketMessage(msg) { - let { type, data } = JSON.parse(msg.data); - if (get(navigating)) await sleep(2000); + let { type, data } = JSON.parse(msg.data); + if (get(navigating)) await sleep(2000); - messages(data)[type] && messages(data)[type](); + 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.ts b/src/lib/store.ts index 42b41127..1183f049 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -2,40 +2,40 @@ import { writable } from "svelte/store"; import { browser } from "$app/environment"; let persistSession = (key, defaultValue = undefined) => { - 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; }; let persistLocal = (key, defaultValue: any = undefined) => { - 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 let account = writable(); diff --git a/src/lib/ticket.ts b/src/lib/ticket.ts index 73ef7716..557b278f 100644 --- a/src/lib/ticket.ts +++ b/src/lib/ticket.ts @@ -3,29 +3,29 @@ 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.ts b/src/lib/tickets.ts index 1f8cbdac..f37fad78 100644 --- a/src/lib/tickets.ts +++ b/src/lib/tickets.ts @@ -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/types.ts b/src/lib/types.ts index 827f96aa..19277ec1 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1,23 +1,23 @@ export interface Message { - author: User; - created_at: number; - recipient: User; + author: User; + created_at: number; + recipient: User; } export interface Note { - created_at: number; - seen: number; + created_at: number; + seen: number; } export interface User { - id: string; + id: string; } export interface Invoice { - aid: string; - id?: string; - memoPrompt?: boolean; - memo?: string; - rate: number; - type?: string; + aid: string; + id?: string; + memoPrompt?: boolean; + memo?: string; + rate: number; + type?: string; } diff --git a/src/lib/upload.ts b/src/lib/upload.ts index 31c235c6..6bc5eaf3 100644 --- a/src/lib/upload.ts +++ b/src/lib/upload.ts @@ -1,18 +1,18 @@ export const upload = async (file, type, progress) => { - 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.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.send(formData); + }); }; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 2ecd332b..96d07703 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -6,355 +6,359 @@ import { page } from "$app/stores"; import { get as getStore } from "svelte/store"; export function scroll(section: any) { - 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; export let punk = (k: string) => - Math.floor((parseInt(k.slice(-2), 16) / 256) * 64) + 1 + ".webp"; + Math.floor((parseInt(k.slice(-2), 16) / 256) * 64) + 1 + ".webp"; export let g = (url: string, fetch: any, headers: object) => - fetch(base + url, { headers }) - .then((r: Response) => r.text()) - .then((body: string) => { - try { - return JSON.parse(body); - } catch (e) { - throw new Error(body); - } - }); + fetch(base + url, { headers }) + .then((r: Response) => r.text()) + .then((body: string) => { + try { + return JSON.parse(body); + } catch (e) { + throw new Error(body); + } + }); export let get = (url: string, 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 = async ( - url: string, - body: object, - headers: HeadersInit | undefined = undefined + url: string, + body: object, + headers: HeadersInit | undefined = undefined, ) => { - headers = { - "content-type": "application/json", - accept: "application/json", - ...headers, - }; + headers = { + "content-type": "application/json", + accept: "application/json", + ...headers, + }; - let response = await 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 response = await 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) => { - let json; - try { - json = JSON.parse(body); - } catch (e) { - throw new Error(body); - } + if (message) throw new Error(message); + throw new Error(text); + }) + .then((body) => { + let json; + try { + json = JSON.parse(body); + } catch (e) { + throw new Error(body); + } - if (json.error instanceof Error) throw json.error; - if (json instanceof Error) throw body; - if (json.name === "Error") throw new Error(json.message); + if (json.error instanceof Error) throw json.error; + if (json instanceof Error) throw body; + if (json.name === "Error") throw new Error(json.message); - return json; - }); + return json; + }); - return response; + return response; }; export let copy = (text: string) => { - navigator.clipboard.writeText(text); - success("Copied!"); + navigator.clipboard.writeText(text); + success("Copied!"); }; export let copyNoNewlines = (text: string) => { - 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: string, locale: string): number { - 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: RegExp[] = [/customers/, /settings/, /payments/]; let recent: string[] = []; export let success = (m: string, clear: boolean = true) => { - if (recent.includes(m)) return; - recent.push(m); - setTimeout(() => (recent = []), 5000); - if (clear) toast.pop(); - toast.push(m, { - theme: { - "--toastBarBackground": "#F5F7FA", - }, - }); + if (recent.includes(m)) return; + recent.push(m); + setTimeout(() => (recent = []), 5000); + if (clear) toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "#F5F7FA", + }, + }); }; export let warning = (m: string, clear: boolean = true) => { - if (clear) toast.pop(); - toast.push(m, { - theme: { - "--toastBarBackground": "#FFCE22", - }, - }); + if (clear) toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "#FFCE22", + }, + }); }; export let fail = (m: string, clear: boolean = true) => { - if (clear) toast.pop(); - toast.push(m, { - theme: { - "--toastBarBackground": "#E93535", - }, - }); + if (clear) toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "#E93535", + }, + }); }; export let info = (m: string) => { - toast.pop(); - toast.push(m, { - theme: { - "--toastBarBackground": "white", - }, - }); + toast.pop(); + toast.push(m, { + theme: { + "--toastBarBackground": "white", + }, + }); }; export let login = async ( - user: { username: string; password: string }, - cookies: any, - ip: string + user: { username: string; password: string }, + cookies: any, + ip: string, ) => { - 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 { user: u, token } = await res.json(); - if (!token) throw new Error("Login failed"); + let { user: u, 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 }; - if (u.language) cookies.set("lang", u.language, opts); - cookies.set("username", user.username, opts); - cookies.set("token", token, opts); + let opts = { path: "/", expires }; + if (u.language) cookies.set("lang", u.language, opts); + cookies.set("username", user.username, opts); + cookies.set("token", token, opts); }; export let auth = (cookies: any) => ({ - authorization: `Bearer ${cookies.get("token")}`, + authorization: `Bearer ${cookies.get("token")}`, }); export let btc = (fiat: number, rate: number): number => - Math.round((fiat * sats) / rate); + Math.round((fiat * sats) / rate); export let fiat = (amount: number, rate: number): number => - (amount * rate) / sats; + (amount * rate) / sats; export let fd = async (req: Request): Promise<any> => { - let obj: Record<string, any> = 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: Record<string, any> = 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: number, currency: string): string => { - try { - return new Intl.NumberFormat("en-US", { - style: "currency", - currency, - }) - .format(s) - .replace("CA", ""); - } catch (e) { - return ""; - } + try { + return new Intl.NumberFormat("en-US", { + style: "currency", + currency, + }) + .format(s) + .replace("CA", ""); + } catch (e) { + return ""; + } }; export let s = (s: number): string => - new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 }).format(s); + new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 }).format(s); export let sat = (s: number): string => "⚡️" + si(Math.abs(s)).toString(); export let si = (s: number) => { - if (s < 1000) return s.toString(); // Return the original number if it's less than 1000 + if (s < 1000) return s.toString(); // Return the original number if it's less than 1000 - const units = ["", "K", "M", "G", "T", "P", "E", "Z"]; - const d = Math.floor(Math.log10(s) / 3); // Calculate the unit index - const scaled = s / Math.pow(1000, d); // Scale the number to the correct unit + const units = ["", "K", "M", "G", "T", "P", "E", "Z"]; + const d = Math.floor(Math.log10(s) / 3); // Calculate the unit index + const scaled = s / Math.pow(1000, d); // Scale the number to the correct unit - return new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format(scaled) + units[d]; + return ( + new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format( + scaled, + ) + units[d] + ); }; export let sats = 100000000; export let back = (): any => - browser && (history.length ? history.go(-1) : goto("/")); + browser && (history.length ? history.go(-1) : goto("/")); export let focus = (el: HTMLElement): any => - browser && screen.width > 1280 && setTimeout(() => el.focus(), 1); + browser && screen.width > 1280 && setTimeout(() => el.focus(), 1); export let select = (el: HTMLInputElement): any => - browser && screen.width > 1280 && setTimeout(() => el.select(), 1); + browser && screen.width > 1280 && setTimeout(() => el.select(), 1); export let sleep = (n: number): Promise<void> => - new Promise((r) => setTimeout(r, n)); + new Promise((r) => setTimeout(r, n)); export let wait = async ( - f: () => boolean | Promise<boolean>, - n: number = 100, - s: number = 300 + f: () => boolean | Promise<boolean>, + n: number = 100, + s: number = 300, ): Promise<boolean> => { - 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: string, salt: Uint8Array) => - 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"], + ); export let types = { - bitcoin: "bitcoin", - liquid: "liquid", - lightning: "lightning", - internal: "internal", - fund: "fund", - ecash: "ecash", - reconcile: "reconcile", + bitcoin: "bitcoin", + liquid: "liquid", + lightning: "lightning", + internal: "internal", + fund: "fund", + ecash: "ecash", + reconcile: "reconcile", }; export let ease = (t: number): number => - t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t; + t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t; export function shuffleArray<T>(array: T[]): void { - 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]]; - } + 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 closest = (a: number[], n: number): number => - a.reduce((prev, curr) => - Math.abs(curr - n) < Math.abs(prev - n) ? curr : prev - ); + a.reduce((prev, curr) => + Math.abs(curr - n) < Math.abs(prev - n) ? curr : prev, + ); export let isLiquid = (text: string): boolean => - text.startsWith("Az") || - text.startsWith("lq1") || - text.startsWith("VJL") || - text.startsWith("VT") || - text.startsWith("XR") || - text.startsWith("XC") || - ((text.startsWith("H") || text.startsWith("G") || text.startsWith("Q")) && - text.length === 34) || - (text.startsWith("ert1q") && text.length === 43) || - (text.startsWith("ex1q") && text.length === 42) || - text.startsWith("el1qq") || - text.startsWith("lq1qq"); + text.startsWith("Az") || + text.startsWith("lq1") || + text.startsWith("VJL") || + text.startsWith("VT") || + text.startsWith("XR") || + text.startsWith("XC") || + ((text.startsWith("H") || text.startsWith("G") || text.startsWith("Q")) && + text.length === 34) || + (text.startsWith("ert1q") && text.length === 43) || + (text.startsWith("ex1q") && text.length === 42) || + text.startsWith("el1qq") || + text.startsWith("lq1qq"); export function getCookie(name: string): string | null { - let nameEQ = name + "="; - let ca = document.cookie.split(";"); - for (let i = 0; i < ca.length; i++) { - let c = ca[i]; - while (c.charAt(0) === " ") c = c.substring(1); - if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); - } - return null; + let nameEQ = name + "="; + let ca = document.cookie.split(";"); + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) === " ") c = c.substring(1); + if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); + } + return null; } export function setCookie(name: string, value: string, seconds: number): void { - const now = new Date(); - now.setTime(now.getTime() + seconds * 1000); - const expires = "expires=" + now.toUTCString(); - document.cookie = name + "=" + value + ";" + expires + ";path=/"; + const now = new Date(); + now.setTime(now.getTime() + seconds * 1000); + const expires = "expires=" + now.toUTCString(); + document.cookie = name + "=" + value + ";" + expires + ";path=/"; } export let network = { - bitcoin: { - bech32: "bc", - pubKeyHash: 0x00, - scriptHash: 0x05, - wif: 0x80, - }, - regtest: { - bech32: "bcrt", - pubKeyHash: 0x6f, - scriptHash: 0xc4, - wif: 0xef, - }, + bitcoin: { + bech32: "bc", + pubKeyHash: 0x00, + scriptHash: 0x05, + wif: 0x80, + }, + regtest: { + bech32: "bcrt", + pubKeyHash: 0x6f, + scriptHash: 0xc4, + wif: 0xef, + }, }[PUBLIC_COINOS_NETWORK]; export let versions = { - bitcoin: { - private: 0x0488ade4, - public: 0x0488b21e, - }, - regtest: { - private: 0x04358394, - public: 0x043587cf, - }, + bitcoin: { + private: 0x0488ade4, + public: 0x0488b21e, + }, + regtest: { + private: 0x04358394, + public: 0x043587cf, + }, }[PUBLIC_COINOS_NETWORK]; |
