From 190c13a338462a7a76ee65e9486e42c0165a65f4 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 3 Jul 2026 15:08:26 -0700 Subject: Ark: wire into the wallet UI - Settings: Ark server card (off by default, per-network presets incl. Second mainnet + local regtest, custom URLs) with balance, coin count, board form (on-chain -> Ark; funding output pinned to vout 0 via the new buildTx noSort option), refresh/consolidate, and recent activity. - Receive: Ark option in the address-type dropdown (QR + copy). - Send: t?ark1 addresses are recognized in the normal send form and route to an Ark confirmation (no mining fee) with a success view. - Balance card: Ark balance line under the on-chain figure. - ArkManager lifecycle: per-wallet instance created on account activation, background sync every 5s (regtest) / 30s, state persisted under the wallet cache key. Verified end-to-end in a real browser (tools/ark/ui-test.js, puppeteer against the regtest stack): receive, send, board, and refresh all green. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy --- src/wallet.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/wallet.js') diff --git a/src/wallet.js b/src/wallet.js index 1972f22..156d2f4 100644 --- a/src/wallet.js +++ b/src/wallet.js @@ -1191,7 +1191,7 @@ export class Wallet { // recipients: [{ address, amount(sats) }] // coinIds: optional array of "txid:vout" to force manual coin control. // sendMax: drain all selected coins to the single recipient. - buildTx({ recipients, feeRate, coinIds = null, sendMax = false }) { + buildTx({ recipients, feeRate, coinIds = null, sendMax = false, noSort = false }) { const pool_ = coinIds ? this.utxos.filter((u) => coinIds.includes(utxoId(u))) : this.utxos.filter((u) => !this.isReserved(utxoId(u))); // skip coins set aside for gifts @@ -1282,7 +1282,10 @@ export class Wallet { feePerByte, network: this.netCfg.net, createTx: true, - bip69: true, + // noSort keeps recipients at their given indexes (change appended last) — + // required when an output's position is protocol-relevant (Ark board + // funding must sit at vout 0). + bip69: !noSort, disableScriptCheck: true, }); if (!sel || !sel.tx) @@ -1533,6 +1536,17 @@ export class Wallet { try { localStorage.setItem(this._reclaimedKey(), JSON.stringify([...this.reclaimedSet()])); } catch {} } + // ---- Ark support ------------------------------------------------------- + // Persisted ArkManager state (vtxos, in-flight action checkpoints, movement + // history — no secrets: vtxo keys are re-derived from the seed). + _arkKey() { return this._cacheKey() + ':ark'; } + loadArkState() { + try { return JSON.parse(localStorage.getItem(this._arkKey()) || 'null'); } catch { return null; } + } + saveArkState(state) { + try { localStorage.setItem(this._arkKey(), JSON.stringify(state)); } catch {} + } + // ---- Boltz swap support ---------------------------------------------- // Persisted swap records (public metadata only — keys/preimage are re-derived // deterministically from the seed via swapNode, so nothing secret is stored). -- cgit v1.2.3