diff options
Diffstat (limited to 'src/features')
| -rw-r--r-- | src/features/ark.js | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/features/ark.js b/src/features/ark.js index 6952fc0..94dfc09 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -494,6 +494,7 @@ export function arkFeature(ctx) { } let arkTimer = null; let arkConnectPromise = null; + let arkInitPromise = null; // the manager's own init, apart from the snapshot gate let arkInitGen = 0; // guards against a stale init() resolving after a wallet switch function stopArk() { @@ -514,6 +515,7 @@ export function arkFeature(ctx) { ark = null; arkInited = null; arkConnectPromise = null; + arkInitPromise = null; // The renewal warning describes the coins of the wallet we're leaving. // Switching accounts used to carry it onto the next one — with the old // wallet's amount and deadline, over the new wallet's balance — and the @@ -663,6 +665,9 @@ export function arkFeature(ctx) { esploraUrl: cfg.esplora, network: getNetwork(), honorsExpired: !!cfg.honorsExpired, + // the server's last published info: the wallet opens on it when the + // server is gone, so coins can still be read and exited + infoHint: (cachedArkInfo(cfg.ark) || {}).info || null, // the wallet's own tx table as a second witness for confirmations — // its data source is user-configurable and often healthier than the // ark preset's esplora from this device @@ -679,9 +684,10 @@ export function arkFeature(ctx) { const inited = mgr.init().then(() => { if (gen !== arkInitGen) return; arkInited = mgr; // readable now; `ark` (and the mailbox) wait for the snapshot - rememberArkInfo(cfg.ark, mgr.info, mgr._tipH); + if (!mgr.offline) rememberArkInfo(cfg.ark, mgr.info, mgr._tipH); render(); }); + arkInitPromise = inited; // The tip: expiries and exit costs are judged against it, and init alone // never asks for it (the first sync does, after the snapshot gate). Ask // now, off the connect path, and remember it for the next refresh. @@ -2938,7 +2944,17 @@ export function arkFeature(ctx) { async function doArkExit(ids = null) { ui.arkBusy = 'exit'; ui.arkError = ''; render(); try { - const mgr = await connectArk(); + // The manager's own init is enough for an exit — the server may be + // gone (that is what a unilateral exit is for), and the snapshot gate + // the full connect also waits on may never clear without the relays. + let mgr = arkView(); + if (!mgr) { + connectArk().catch(() => {}); + for (let i = 0; i < 50 && !arkInitPromise; i++) await new Promise((r) => setTimeout(r, 100)); + try { await arkInitPromise; } catch {} + mgr = arkView(); + } + if (!mgr) throw new Error(t('arkNotConnected')); const spendables = exitableCoins(mgr.state, mgr._tipH || 0).filter((v) => !ids || ids.includes(v.id)); if (!spendables.length) throw new Error(freeCoins(mgr.state).length ? t('arkExitNoneExitable') : t('arkNotConnected')); // Fees are paid hop by hop from Savings as the exit unrolls — an exit |
