diff options
| author | Adam Soltys <[email protected]> | 2024-11-26 13:08:08 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-11-26 13:20:53 -0800 |
| commit | 9b3e117eafbba224b86dd7f8b3c56a0370f72d5b (patch) | |
| tree | a670c3ae954d5075c851126c2aca7a1a45d1b41d /src/lib | |
| parent | 2761363d694d3f24600abbe656769f64d7a67605 (diff) | |
| download | coinos-ui-9b3e117eafbba224b86dd7f8b3c56a0370f72d5b.tar.gz coinos-ui-9b3e117eafbba224b86dd7f8b3c56a0370f72d5b.zip | |
bip21 and socket fixes
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/bip21.ts | 48 | ||||
| -rw-r--r-- | src/lib/invoice.ts | 1 | ||||
| -rw-r--r-- | src/lib/parse.ts | 32 | ||||
| -rw-r--r-- | src/lib/socket.ts | 24 | ||||
| -rw-r--r-- | src/lib/utils.ts | 4 |
5 files changed, 88 insertions, 21 deletions
diff --git a/src/lib/bip21.ts b/src/lib/bip21.ts new file mode 100644 index 00000000..2642afab --- /dev/null +++ b/src/lib/bip21.ts @@ -0,0 +1,48 @@ +export function decode(uri, allowedSchemes = ["bitcoin", "liquidnetwork"]) { + // Determine the scheme from the URI + const split = uri.indexOf(":"); + if (split === -1) { + throw new Error("Invalid URI: Missing scheme"); + } + + const urnScheme = uri.slice(0, split).toLowerCase(); + if (!allowedSchemes.includes(urnScheme)) { + throw new Error(`Invalid scheme: ${urnScheme}`); + } + + // Extract address and query string + const queryStart = uri.indexOf("?"); + const address = uri.slice( + split + 1, + queryStart === -1 ? undefined : queryStart, + ); + const query = queryStart === -1 ? "" : uri.slice(queryStart + 1); + const options = Object.fromEntries(new URLSearchParams(query)); + + const n = Number(options?.amount); + if (!Number.isFinite(n)) throw new Error("Invalid amount"); + if (n < 0) throw new Error("Invalid amount"); + + return { scheme: urnScheme, address, options }; +} + +export function encode( + address, + options = { amount: "" }, + urnScheme = "bitcoin", +) { + if (!address || typeof address !== "string") { + throw new TypeError("Invalid address"); + } + + if (!["bitcoin", "liquidnetwork"].includes(urnScheme)) { + throw new Error(`Unsupported scheme: ${urnScheme}`); + } + + const n = Number(options?.amount); + if (!Number.isFinite(n)) throw new Error("Invalid amount"); + if (n < 0) throw new Error("Invalid amount"); + + const query = new URLSearchParams(options).toString(); + return `${urnScheme}:${address}${query ? `?${query}` : ""}`; +} diff --git a/src/lib/invoice.ts b/src/lib/invoice.ts index 9563d924..a48e02a4 100644 --- a/src/lib/invoice.ts +++ b/src/lib/invoice.ts @@ -2,7 +2,6 @@ import { auth, get, post } from "$lib/utils"; import { redirect } from "@sveltejs/kit"; export default async ({ cookies, request }) => { - console.log("LOADING"); const form = await request.formData(); const aid = form.get("aid") || cookies.get("aid"); diff --git a/src/lib/parse.ts b/src/lib/parse.ts index 6483aaa0..7ddb2104 100644 --- a/src/lib/parse.ts +++ b/src/lib/parse.ts @@ -1,7 +1,7 @@ import { PUBLIC_DOMAIN } from "$env/static/public"; +import { decode } from "$lib/bip21"; import { get, isLiquid, post, sats } from "$lib/utils"; import { redirect } from "@sveltejs/kit"; -import bip21 from "bip21"; import { validate } from "bitcoin-address-validation"; export default async (s, host) => { @@ -21,6 +21,23 @@ export default async (s, host) => { } catch (e) {} } + // bitcoin + if ( + t.toLowerCase().startsWith("bitcoin:") || + t.toLowerCase().startsWith("liquidnetwork:") + ) { + ({ + address: t, + options: { amount }, + } = decode(t)); + } + + if (validate(t) || isLiquid(t)) { + let r = `/send/bitcoin/${t}`; + if (amount) r += `/${Math.round(amount * sats)}`; + redirect(307, r); + } + // lightning if (t.toLowerCase().startsWith("lightning:")) t = t.toLowerCase().replace("lightning:", ""); @@ -47,19 +64,6 @@ export default async (s, host) => { } } - // bitcoin - if (t.toLowerCase().startsWith("bitcoin:")) - ({ - address: t, - options: { amount }, - } = bip21.decode(t)); - - if (validate(t) || isLiquid(t)) { - let r = `/send/bitcoin/${t}`; - if (amount) r += `/${Math.round(amount * sats)}`; - redirect(307, r); - } - if (t.startsWith("cashu")) { const { id } = await post("/cash", { token: t }); redirect(307, `/ecash/${id}`); diff --git a/src/lib/socket.ts b/src/lib/socket.ts index 566e989d..bd8494fa 100644 --- a/src/lib/socket.ts +++ b/src/lib/socket.ts @@ -3,9 +3,10 @@ import { navigating, page } from "$app/stores"; import { PUBLIC_SOCKET } from "$env/static/public"; import { event, invoice, last, request } from "$lib/store"; import { s, sleep, success, wait } from "$lib/utils"; +import cookies from "js-cookie"; import { get } from "svelte/store"; -let socket; +export let socket; let token; export const auth = () => token && send("login", token); @@ -13,8 +14,9 @@ export const auth = () => token && send("login", token); export const send = async (type, data) => { try { await wait(() => socket && socket.readyState === 1, 1000, 10); - } catch (e: any) { - if (e.message === "timeout") reconnectToWebsocket(); + } catch (e) { + const { message } = e as Error; + if (message === "timeout") reconnectToWebsocket(); } await wait(() => socket.readyState === 1, 1000, 10); @@ -47,8 +49,14 @@ export const messages = (data) => ({ url: { pathname }, } = get(page); + const username = cookies.get("username"); + if (amount > 0) { - if (pathname.includes("receive")) { + if ( + pathname.includes(`/${username}`) || + pathname.includes("/receive") || + pathname.includes("/invoice") + ) { await wait(() => !get(navigating)); await goto(`/invoice/${iid}`); } else success(`${confirmed ? "Received" : "Detected"} ⚡️${s(amount)}!`); @@ -63,7 +71,14 @@ const maxReconnectDelay = 16000; let currentReconnectDelay = initialReconnectDelay; +let connecting; export function connect(t) { + if (connecting) return; + connecting = true; + setTimeout(() => { + connecting = false; + }, 5000); + token = t; if (socket) return auth(); @@ -87,6 +102,7 @@ async function onWebsocketMessage(msg) { function onWebsocketOpen() { currentReconnectDelay = initialReconnectDelay; + send("heartbeat", token); } function onWebsocketClose() { diff --git a/src/lib/utils.ts b/src/lib/utils.ts index a15bb8e7..dc7182e3 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -151,7 +151,7 @@ export const info = (m: string) => { export const login = async ( user: { username: string; password: string }, - cookies: any, + cookies, ip: string, ) => { const maxAge = 380 * 24 * 60 * 60; @@ -182,7 +182,7 @@ export const login = async ( cookies.set("token", token, opts); }; -export const auth = (cookies: any) => ({ +export const auth = (cookies) => ({ authorization: `Bearer ${cookies.get("token")}`, }); |
