aboutsummaryrefslogtreecommitdiffstats
path: root/src/nwc-respond.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-14 09:06:02 -0700
committerAdam Soltys <[email protected]>2026-09-14 09:06:02 -0700
commit671d2a96474f59ca9234c876ce6604d03de95727 (patch)
treed732896288985033c0531b70b7bcad0cc388cb00 /src/nwc-respond.js
parent6394de43d4e596aaeddd2b262bb7a595679d8fbc (diff)
downloadcoinosv3-671d2a96474f59ca9234c876ce6604d03de95727.tar.gz
coinosv3-671d2a96474f59ca9234c876ce6604d03de95727.zip
One device pays a zap, whichever of them heard it first.
Every awake device of a wallet hears a wallet-connect pay request within the same second, and the per-tab lock only reaches one browser profile: two profiles on one laptop each locked an HTLC for the same 21-sat zap. The push notifier now hands each pay request to the first device that claims it; a device that loses the claim stands down silently, and a device that cannot reach the notifier answers as before so nobody goes quiet over a hiccup. The worker path claims the same way. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01QYJfZ4A1TDCEY4Foq3CApR
Diffstat (limited to 'src/nwc-respond.js')
-rw-r--r--src/nwc-respond.js14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/nwc-respond.js b/src/nwc-respond.js
index 9fdfcff..bab25b0 100644
--- a/src/nwc-respond.js
+++ b/src/nwc-respond.js
@@ -183,6 +183,19 @@ export async function respondFromBg(data, {
return !!(await r.json()).answered;
} catch { return false; }
};
+ // ...and hands each pay request to the first device that claims it, so
+ // two awake devices don't each lock an HTLC for one zap. Unreachable →
+ // proceed: a lone worker must not go silent over a notifier hiccup.
+ const claim = async () => {
+ try {
+ const r = await fetchFn(`${notifier}/claim`, {
+ method: 'POST', headers: { 'content-type': 'application/json' },
+ body: JSON.stringify({ event: ev.id, by: `sw-${walletKey}`.slice(0, 64) }),
+ });
+ if (!r.ok) return true;
+ return (await r.json()).ok !== false;
+ } catch { return true; }
+ };
if (method === 'get_info') {
await publish({
@@ -268,6 +281,7 @@ export async function respondFromBg(data, {
}
return true;
};
+ if (!(await claim())) { log('another device claimed this request — standing down'); return true; }
const deadline = Date.now() + PAY_WAIT_MS;
let a = null;
for (let attempt = 0; ; attempt++) {