diff options
| author | Adam Soltys <[email protected]> | 2026-03-13 14:25:51 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-03-13 14:25:51 -0700 |
| commit | 91f0517b8d72a2a45c7f6423597808b2e4a6f0aa (patch) | |
| tree | 5cd92fc6aeb65307508e726ffbace0c1549700b8 | |
| parent | 7e0dab611ea6d6a6f764470af9b0c53055e05d74 (diff) | |
| download | coinos-ui-91f0517b8d72a2a45c7f6423597808b2e4a6f0aa.tar.gz coinos-ui-91f0517b8d72a2a45c7f6423597808b2e4a6f0aa.zip | |
delegation
6 files changed, 49 insertions, 34 deletions
diff --git a/src/lib/ark.ts b/src/lib/ark.ts index a848e5c7..42ab822a 100644 --- a/src/lib/ark.ts +++ b/src/lib/ark.ts @@ -7,6 +7,8 @@ export const arkServerUrl = { bitcoin: "https://arkade.computer", regtest: "http://localhost:7070", }[PUBLIC_COINOS_NETWORK || "regtest"]; +// Delegator runs on the coinos server, accessed via /api proxy +const delegatorUrl = "/api"; export const arkkey = persistLocal("arkkey", ""); export const arkaid = persistLocal("arkaid", ""); @@ -53,12 +55,14 @@ export const getWallet = async () => { } if (walletInstance && walletKey === key) return walletInstance; - const { SingleKey, Wallet } = await loadArkSdk(); + const { SingleKey, Wallet, RestDelegatorProvider } = await loadArkSdk(); const identity = SingleKey.fromHex(key); + const delegatorProvider = new RestDelegatorProvider(delegatorUrl); walletInstance = await Wallet.create({ identity, arkServerUrl, + delegatorProvider, }); walletKey = key; return walletInstance; @@ -305,6 +309,7 @@ const _syncTransactions = async (aid: string) => { const result = await post("/ark/sync", { transactions, aid, balance, arkAddress: walletAddr }); cacheVaultSnapshot(); // fire-and-forget + delegateVtxos(); // fire-and-forget return result; }; @@ -496,6 +501,8 @@ export const refresh = async () => { const vtxos = await wallet.getVtxos({ spendableOnly: false }); if (vtxos?.length) addProcessedVtxos(vtxos.map(vtxoKey)); } + + delegateVtxos(); // fire-and-forget }; export const settle = async () => { @@ -511,6 +518,31 @@ export const settle = async () => { // ignores renewed VTXOs (they get new txids after an Ark round) const vtxos = await wallet.getVtxos({ spendableOnly: false }); if (vtxos?.length) addProcessedVtxos(vtxos.map(vtxoKey)); + + delegateVtxos(); // fire-and-forget +}; + +export const delegateVtxos = async () => { + try { + const wallet = await getWallet(); + if (!wallet) return; + if (!wallet.delegatorManager) return; + + const vtxos = await wallet.getVtxos({ spendableOnly: true }); + if (!vtxos?.length) return; + + const address = await wallet.getAddress(); + const { delegated, failed } = await wallet.delegatorManager.delegate(vtxos, address); + + if (delegated.length > 0) { + console.log("[ark] delegated", delegated.length, "vtxos for renewal"); + } + if (failed.length > 0) { + console.warn("[ark] delegation failed for", failed.length, "groups"); + } + } catch (e: any) { + console.warn("[ark] delegation failed:", e.message); + } }; // Service Worker wallet for background fund notifications diff --git a/src/routes/(app)/payment/[id]/+page.svelte b/src/routes/(app)/payment/[id]/+page.svelte index 03023e8a..3b41cc4f 100644 --- a/src/routes/(app)/payment/[id]/+page.svelte +++ b/src/routes/(app)/payment/[id]/+page.svelte @@ -249,17 +249,6 @@ {@render copyable("Child Txid", p.childTxid, `${expl}/tx/${p.childTxid}`)} {/if} - {#if canBump} - <div class="py-4 border-b border-base-300 space-y-2"> - <button type="button" class="btn btn-accent w-full" onclick={bump} disabled={bumpLoading}> - {bumpLoading ? "Bumping..." : "Speed up"} - </button> - {#if bumpError} - <div class="text-red-600 text-sm text-center">{bumpError}</div> - {/if} - </div> - {/if} - {#if type === types.lightning || type === types.bolt12} {@render copyable($t("payments.invoice"), hash)} {@render copyable($t("payments.preimage"), ref)} @@ -277,8 +266,23 @@ {@render copyable("Address", hash, `${expl}/address/${hash}`)} {/if} + {#if (type === "bitcoin" || type === "liquid") && amount < 0 && p.address} + {@render copyable("Address", p.address, `${expl}/address/${p.address}`)} + {/if} + {#if path} {@render copyable("Path", path)} {/if} + + {#if canBump} + <div class="py-4 space-y-2"> + <button type="button" class="btn btn-accent w-full" onclick={bump} disabled={bumpLoading}> + {bumpLoading ? "Bumping..." : "Speed up"} + </button> + {#if bumpError} + <div class="text-red-600 text-sm text-center">{bumpError}</div> + {/if} + </div> + {/if} </div> </div> diff --git a/src/routes/(app)/send/ark/[address]/+layout.server.ts b/src/routes/(app)/send/ark/[address]/+layout.server.ts index 18fb7aed..b17d89bc 100644 --- a/src/routes/(app)/send/ark/[address]/+layout.server.ts +++ b/src/routes/(app)/send/ark/[address]/+layout.server.ts @@ -7,13 +7,6 @@ export async function load({ cookies, params, parent, url }) { const { address, amount } = params; let account = await get(`/account/${aid}`, auth(cookies)); - // Fall back to custodial if cookie points to ark account - if (account.type === "ark" && aid !== user.id) { - aid = user.id; - account = await get(`/account/${aid}`, auth(cookies)); - cookies.set("aid", aid, { path: "/", maxAge: 86400, httpOnly: false }); - } - let invoice; try { invoice = await get(`/invoice/${address}`); diff --git a/src/routes/(app)/send/ark/[address]/+page.server.ts b/src/routes/(app)/send/ark/[address]/+page.server.ts index 83a5050f..086e6daa 100644 --- a/src/routes/(app)/send/ark/[address]/+page.server.ts +++ b/src/routes/(app)/send/ark/[address]/+page.server.ts @@ -7,12 +7,5 @@ export async function load({ cookies, parent, url }) { let aid = url.searchParams.get("aid") || cookies.get("aid") || user.id; let account = await get(`/account/${aid}`, auth(cookies)); - // Fall back to custodial if cookie points to ark account - if (account.type === "ark" && aid !== user.id) { - aid = user.id; - account = await get(`/account/${aid}`, auth(cookies)); - cookies.set("aid", aid, { path: "/", maxAge: 86400, httpOnly: false }); - } - return { balance: account.balance, rate: rates[user.currency] }; } diff --git a/src/routes/(app)/send/ark/[address]/[amount]/[...feeRate]/+page.server.ts b/src/routes/(app)/send/ark/[address]/[amount]/[...feeRate]/+page.server.ts index ee0775d3..37a0f068 100644 --- a/src/routes/(app)/send/ark/[address]/[amount]/[...feeRate]/+page.server.ts +++ b/src/routes/(app)/send/ark/[address]/[amount]/[...feeRate]/+page.server.ts @@ -9,14 +9,6 @@ export async function load({ params: { address, amount }, cookies, parent, url } let account = await get(`/account/${aid}`, auth(cookies)); - // If cookie points to an ark account but user is sending TO an ark address, - // fall back to custodial account — ark-to-ark sends use client-side wallet - if (account.type === "ark" && aid !== user.id) { - aid = user.id; - account = await get(`/account/${aid}`, auth(cookies)); - cookies.set("aid", aid, { path: "/", maxAge: 86400, httpOnly: false }); - } - if (account.type === "bitcoin") { const inv = await post( "/invoice", diff --git a/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte b/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte index 86bad61c..7b2c9ccf 100644 --- a/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte +++ b/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte @@ -281,6 +281,7 @@ <form method="POST" use:enhance={handler}> <input name="pin" value={$pin} type="hidden" /> + <input name="address" value={address} type="hidden" /> <input name="hex" value={hex} type="hidden" /> <input name="rate" value={$rate} type="hidden" /> <input name="aid" value={account.id} type="hidden" /> |
