diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ark/manager.js | 13 | ||||
| -rw-r--r-- | src/features/ark.js | 5 |
2 files changed, 13 insertions, 5 deletions
diff --git a/src/ark/manager.js b/src/ark/manager.js index 7be74fe..01e257a 100644 --- a/src/ark/manager.js +++ b/src/ark/manager.js @@ -1346,11 +1346,16 @@ export class ArkManager { if (action.step === 'funded') { const need = this.info.requiredBoardConfirmations; const status = await this.chain.getTxStatus(action.fundingTxid); - // record progress so the UI can say WHERE the wait is (n/need confs) - const confs = status?.confirmed ? (await this.chain.tipHeight()) - status.block_height + 1 : 0; + // record progress so the UI can say WHERE the wait is (n/need confs). + // A confirmed status proves at least ONE confirmation on its own — the + // tip fetch only refines the count, so its failure (rate limits) must + // not strand a confirmed board at "0/need" forever. + let confs = 0; + if (status?.confirmed) { + const tip = await this.chain.tipHeight().catch(() => null); + confs = tip != null && Number.isFinite(tip) ? tip - status.block_height + 1 : 1; + } if (confs !== action.confs || need !== action.needConfs) { action.confs = confs; action.needConfs = need; this._save(); } - // NB not `confs < need`: a failed tip fetch makes confs NaN, which must - // wait for the next sync rather than slip past the comparison if (!(confs >= need)) return; // retried on sync const fundingOutpointRaw = new Uint8Array(36); diff --git a/src/features/ark.js b/src/features/ark.js index 5641186..cefb877 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -343,7 +343,10 @@ export function arkFeature(ctx) { // them. Publishing on connect guarantees every device's ark balance // reaches the relay (and gets merged) without needing a transaction first. if (mgr.state && (mgr.state.vtxos || []).length) { try { wallet.saveCache(); } catch {} } - const tick = () => mgr.sync().catch(() => {}) + // A failed mailbox read must not starve the action drives: boards and + // refreshes progress on chain state alone, so push them even when the + // sync itself errored. + const tick = () => mgr.sync().catch(() => mgr.resumePending().catch(() => {})) .then(() => driveExits(mgr)).catch(() => {}) .then(() => { if (ark === mgr) return maybeAutoRefresh(mgr); }).catch(() => {}) .then(() => { if (ark === mgr) return maybeAutoWithdraw(mgr); }).catch(() => {}); |
