aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/nostr-login.js5
-rw-r--r--tools/nostr-login-test.js19
2 files changed, 23 insertions, 1 deletions
diff --git a/src/nostr-login.js b/src/nostr-login.js
index 00106c4..7addfc5 100644
--- a/src/nostr-login.js
+++ b/src/nostr-login.js
@@ -90,8 +90,11 @@ export async function extensionSigner() {
export async function bunkerSigner(uri, { onAuth } = {}) {
const bp = await parseBunkerInput(String(uri || '').trim());
if (!bp) throw new Error('not a bunker:// address');
+ if (!bp.relays || !bp.relays.length) throw new Error('that bunker address lists no relays');
const local = generateSecretKey();
- const signer = new BunkerSigner(local, bp, {
+ // NB the pointer goes through fromBunker — the constructor takes params
+ // only, and passing the pointer there leaves the signer without one.
+ const signer = BunkerSigner.fromBunker(local, bp, {
onauth: (url) => { if (onAuth) onAuth(url); else if (typeof window !== 'undefined') window.open(url, '_blank'); },
});
await signer.connect();
diff --git a/tools/nostr-login-test.js b/tools/nostr-login-test.js
index 42580fe..0440333 100644
--- a/tools/nostr-login-test.js
+++ b/tools/nostr-login-test.js
@@ -73,5 +73,24 @@ console.log('\n[NIP-98 auth]');
check('binds the body hash', tag('payload') === hex.encode(sha(new TextEncoder().encode(body))));
}
+console.log('\n[bunker (NIP-46) wiring]');
+{
+ const { bunkerSigner } = await import('../src/nostr-login.js');
+ const { parseBunkerInput } = await import('nostr-tools/nip46');
+ // a real Amethyst-issued address shape
+ const uri = 'bunker://81029479a85c3f2f0c8d7ca9fbd92923942e2254e873d93c1c7095f068c83a85'
+ + '?relay=wss%3A%2F%2Frelay.damus.io%2F&relay=wss%3A%2F%2Fnos.lol%2F&secret=4wdWEsG7RDzCaBt6p9ovvk0uMX6ENh2J';
+ const bp = await parseBunkerInput(uri);
+ check('parses an Amethyst bunker address', !!bp && bp.relays.length === 2 && !!bp.secret);
+ // Constructing must not throw synchronously: the failure this guards against
+ // is passing the pointer to the constructor, which leaves signer.bp unset
+ // and dies with "reading 'pubkey'" before any network call.
+ let err = null;
+ const p = bunkerSigner(uri, { onAuth: () => {} }).catch((e) => { err = e; });
+ await Promise.race([p, new Promise((r) => setTimeout(r, 1500))]);
+ check('constructs without a pubkey error', !/reading 'pubkey'|undefined/.test(String(err && err.message)), err && err.message);
+ check('rejects a non-bunker string', await bunkerSigner('nope').then(() => false, (e) => /bunker/.test(e.message)));
+}
+
console.log(fails ? `\n❌ ${fails} failure(s)` : '\n✅ nostr login behaves');
process.exit(fails ? 1 : 0);