diff options
| author | Adam Soltys <[email protected]> | 2026-10-28 00:22:33 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-28 00:22:33 -0700 |
| commit | 2302a4f0e25562c4d4977990918b86d4c6baba27 (patch) | |
| tree | 7c187291cdafbfb50b8124dc3db7156ba258af79 /src/features/ark.js | |
| parent | f5c07454284a123070a0f0159919fc8c2de2b825 (diff) | |
| download | coinosv3-2302a4f0e25562c4d4977990918b86d4c6baba27.tar.gz coinosv3-2302a4f0e25562c4d4977990918b86d4c6baba27.zip | |
The background worker's key window is 250 keys (was 25: PullCap's hourly subscription ran out after 19 payments with the app closed, "key window exhausted"), derived once per account and memoized; 60 receive preimages (was 15). When the worker can't act on a request it still wakes the user, and now leaves a "wait, open the app" error with the notifier that goes out only if nobody answers within 20 s, so the other app hears something instead of silence and a sibling's real payment is never shouted over. A request older than its two-minute window (a push that waited at APNs) is ignored quietly instead of showing "Payment request"
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'src/features/ark.js')
| -rw-r--r-- | src/features/ark.js | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/features/ark.js b/src/features/ark.js index 0a529c5..b8e83a7 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -995,6 +995,26 @@ export function arkFeature(ctx) { // connections/offer belong to the nwc feature; when it isn't the caller // (an auto-withdraw setting changed, say) carry forward what's mirrored // rather than blanking someone's wallet connections. + // The mirror carries hundreds of pre-derived keys (BG_KEY_LOOKAHEAD) and + // is rewritten after every state change: derive each index once per + // account, not once per write. + const bgKeyMemo = new WeakMap(); // account node -> Map('chain:i' -> hex) + function bgKeyFor(account) { + let m = bgKeyMemo.get(account); + if (!m) { m = new Map(); bgKeyMemo.set(account, m); } + const chains = new Map(); + return (chain, i) => { + const k = chain + ':' + i; + let v = m.get(k); + if (!v) { + let node = chains.get(chain); + if (!node) { node = account.deriveChild(chain); chains.set(chain, node); } + v = hex.encode(node.deriveChild(i).privateKey); + m.set(k, v); + } + return v; + }; + } async function writeBgMirror(connections, offer, prefs) { const cfg = getArkConfig(); if (!cfg || !ark || !ark.info || !ark.state) return; @@ -1006,7 +1026,7 @@ export function arkFeature(ctx) { ark: { arkUrl: cfg.ark, esploraUrl: cfg.esplora, network: getNetwork(), serverPubkey: ark.info.serverPubkey, honorsExpired: !!cfg.honorsExpired }, mgrState: ark.state, custody: getCustody(), - keyFor: (chain, i) => hex.encode(ark.account.deriveChild(chain).deriveChild(i).privateKey), + keyFor: bgKeyFor(ark.account), connections, offer, autowithdraw: await awMirror(prev), |
