diff options
| author | Adam Soltys <[email protected]> | 2026-08-01 11:02:37 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-01 11:02:37 -0700 |
| commit | 0519a79ac05ec983ae7ad8d4292f5cfa9fa321a9 (patch) | |
| tree | 6939dd691379a5642d47c51c866dc98f846c24af /src/nostr.js | |
| parent | d8d2746f16d1bdcb71e1409a90871b65117d026c (diff) | |
| download | coinosv3-0519a79ac05ec983ae7ad8d4292f5cfa9fa321a9.tar.gz coinosv3-0519a79ac05ec983ae7ad8d4292f5cfa9fa321a9.zip | |
NWC: own the relay set instead of borrowing the sync feature's
The connection URI advertised up to four relays (sync relays + profile
relays) while the subscription only ever listened on the sync relay, so a
client could publish its request somewhere hal wasn't and spin forever
waiting for a reply. Amethyst did exactly that.
NWC now has its own relay list used for all three things that must agree:
the URI, the subscription, and the replies. It no longer depends on device
sync being enabled, which would otherwise have made the whole wallet service
a silent no-op.
Also republish the kind 13194 capability event on every start — a client that
can't find it just spins, and a single publish at creation time is easy for a
relay to miss.
The relay transport is now injectable so the protocol can be exercised
without a live relay (tools/nwc-test.js).
Co-Authored-By: Claude Fable 5 <[email protected]>
Diffstat (limited to 'src/nostr.js')
| -rw-r--r-- | src/nostr.js | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/nostr.js b/src/nostr.js index 652c579..1a86499 100644 --- a/src/nostr.js +++ b/src/nostr.js @@ -23,6 +23,20 @@ import { base64urlnopad } from '@scure/base'; // CLOSE-after-EOSE handshake) cleanly, so we never send on a half-closed socket. const pool = new SimplePool(); +// Subscribe / publish on an explicit relay set, independent of the sync +// feature's configuration. NWC needs this: the relays it advertises in a +// connection URI must be exactly the ones it listens on, or a client's +// request lands somewhere the wallet isn't and it waits forever. +export function subscribeOn(relays, filter, onEvent) { + try { + const sub = pool.subscribeMany(relays, [filter], { onevent: onEvent }); + return () => { try { sub.close(); } catch {} }; + } catch { return () => {}; } +} +export async function publishOn(relays, evt) { + try { await Promise.allSettled(pool.publish(relays, evt)); return true; } catch { return false; } +} + // --- locking a gift to a recipient's Nostr key --------------------------- // An npub or 64-hex nostr pubkey → hex, or null if it isn't one. // NIP-47 wallet services sign with their own per-connection key and must |
