signet-login 0.10.2 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/dist/signers.d.ts +17 -5
- package/dist/signers.js +51 -6
- package/dist/signet-login.d.ts +2 -2
- package/dist/signet-login.iife.js +16 -16
- package/dist/signet-login.js +6 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,9 +164,22 @@ await fetch('/api/login', {
|
|
|
164
164
|
});
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
-
Headless exports include `hasNip07`, `createNip07Signer`, `createBunkerSigner`, `createBunkerSignerFromNostrConnect`, `buildNostrConnectUri`, `createLocalSignerFromNsec`, `createLoginAuthEvent`, `createSessionFromSigner`, and `generateSecretKey`.
|
|
167
|
+
Headless exports include `hasNip07`, `createNip07Signer`, `createBunkerSigner`, `createBunkerSignerFromNostrConnect`, `buildNostrConnectUri`, `buildBunkerUriFromNostrConnectUri`, `isBunkerUri`, `isNostrConnectUri`, `isSupportedPairingUri`, `createLocalSignerFromNsec`, `createLoginAuthEvent`, `createSessionFromSigner`, and `generateSecretKey`.
|
|
168
168
|
The IIFE bundle attaches the same helpers to `window.Signet`.
|
|
169
169
|
|
|
170
|
+
### NostrConnect and bunker roles
|
|
171
|
+
|
|
172
|
+
NIP-46 has two URI directions:
|
|
173
|
+
|
|
174
|
+
| URI | Producer | Consumer | Use |
|
|
175
|
+
|---|---|---|---|
|
|
176
|
+
| `nostrconnect://...` | The app / Signet Access client | Signer app scans or opens it | First pairing, where the app advertises its client pubkey, relays, requested permissions, and one-time secret |
|
|
177
|
+
| `bunker://...` | The signer / bunker | App connects to it | Reconnect, paste/scan bunker flows, native clients, and persisted sessions |
|
|
178
|
+
|
|
179
|
+
`createBunkerSignerFromNostrConnect()` waits for the signer response and then stores the equivalent `bunker://` reconnect URI internally, preserving the relay list and secret. This matters for apps such as Canary, Pallasite, and Axenstax: the user can pair once with NostrConnect, then `restoreSession()` can reconnect with the same stable client key instead of showing a fresh pairing request.
|
|
180
|
+
|
|
181
|
+
Signet Access is the app-side session broker. Identity creation, recovery, and derived personas belong in Signet, Heartwood, and `nsec-tree`; app integrations should consume the returned pubkey and capability flags instead of deriving identities inside the login SDK.
|
|
182
|
+
|
|
170
183
|
### Custom storage
|
|
171
184
|
|
|
172
185
|
By default, Signet Access stores session state in localStorage under `signet:login.*`. Pass `storage` when you need encrypted, async, IndexedDB, server-backed, or test storage:
|
package/dist/signers.d.ts
CHANGED
|
@@ -85,11 +85,23 @@ export declare function buildNostrConnectUri(input: {
|
|
|
85
85
|
appUrl?: string;
|
|
86
86
|
}): string;
|
|
87
87
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
88
|
+
* Convert an app-generated `nostrconnect://` pairing URI into the equivalent
|
|
89
|
+
* signer-published `bunker://` reconnect URI once the signer pubkey is known.
|
|
90
|
+
*
|
|
91
|
+
* `nostrconnect://` is a one-time app-to-signer invitation; it only contains
|
|
92
|
+
* the client pubkey. After the signer responds, future restores should use
|
|
93
|
+
* `bunker://signerPubkey?...` with the same relays and secret.
|
|
94
|
+
*/
|
|
95
|
+
export declare function buildBunkerUriFromNostrConnectUri(nostrConnectUri: string, signerPubkeyHex: string): string;
|
|
96
|
+
export declare function isBunkerUri(value: string): boolean;
|
|
97
|
+
export declare function isNostrConnectUri(value: string): boolean;
|
|
98
|
+
export declare function isSupportedPairingUri(value: string): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Connect a bunker session from a `bunker://` URI or NIP-05 identifier. Pass
|
|
101
|
+
* `clientSecretKey` to bind a stable client pubkey the signer can auto-approve
|
|
102
|
+
* (see `loadOrCreatePersistentClientSk`); when omitted a fresh ephemeral key is
|
|
103
|
+
* generated, which a per-pubkey-approving bunker will treat as a new,
|
|
104
|
+
* unapproved client.
|
|
93
105
|
*/
|
|
94
106
|
export declare function createBunkerSigner(input: {
|
|
95
107
|
uri: string;
|
package/dist/signers.js
CHANGED
|
@@ -118,7 +118,8 @@ export async function createBunkerSignerFromNostrConnect(input) {
|
|
|
118
118
|
await bunker.close().catch(() => { });
|
|
119
119
|
throw new Error('invalid-pubkey-from-bunker');
|
|
120
120
|
}
|
|
121
|
-
|
|
121
|
+
const normalizedBunkerUri = buildBunkerUriFromNostrConnectUri(uri, pubkey);
|
|
122
|
+
return new BunkerSignerImpl(pubkey.toLowerCase(), bunker, normalizedBunkerUri, clientSecretKey);
|
|
122
123
|
}
|
|
123
124
|
/**
|
|
124
125
|
* Build a NIP-46 `nostrconnect://` URI for the app-initiated flow. The
|
|
@@ -149,6 +150,50 @@ export function buildNostrConnectUri(input) {
|
|
|
149
150
|
params.set('url', input.appUrl);
|
|
150
151
|
return `nostrconnect://${clientPubkeyHex}?${params.toString()}`;
|
|
151
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Convert an app-generated `nostrconnect://` pairing URI into the equivalent
|
|
155
|
+
* signer-published `bunker://` reconnect URI once the signer pubkey is known.
|
|
156
|
+
*
|
|
157
|
+
* `nostrconnect://` is a one-time app-to-signer invitation; it only contains
|
|
158
|
+
* the client pubkey. After the signer responds, future restores should use
|
|
159
|
+
* `bunker://signerPubkey?...` with the same relays and secret.
|
|
160
|
+
*/
|
|
161
|
+
export function buildBunkerUriFromNostrConnectUri(nostrConnectUri, signerPubkeyHex) {
|
|
162
|
+
if (!/^[0-9a-f]{64}$/i.test(signerPubkeyHex))
|
|
163
|
+
throw new Error('invalid-signer-pubkey');
|
|
164
|
+
let parsed;
|
|
165
|
+
try {
|
|
166
|
+
parsed = new URL(nostrConnectUri);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
throw new Error('invalid-nostrconnect-uri');
|
|
170
|
+
}
|
|
171
|
+
if (parsed.protocol !== 'nostrconnect:')
|
|
172
|
+
throw new Error('invalid-nostrconnect-uri');
|
|
173
|
+
const relays = parsed.searchParams.getAll('relay').map(relay => relay.trim()).filter(Boolean);
|
|
174
|
+
if (relays.length === 0)
|
|
175
|
+
throw new Error('relay-url-required');
|
|
176
|
+
for (const relayUrl of relays) {
|
|
177
|
+
if (!/^wss?:\/\//.test(relayUrl))
|
|
178
|
+
throw new Error('invalid-relay-url');
|
|
179
|
+
}
|
|
180
|
+
const secret = parsed.searchParams.get('secret');
|
|
181
|
+
const params = new URLSearchParams();
|
|
182
|
+
for (const relayUrl of relays)
|
|
183
|
+
params.append('relay', relayUrl);
|
|
184
|
+
if (secret)
|
|
185
|
+
params.set('secret', secret);
|
|
186
|
+
return `bunker://${signerPubkeyHex.toLowerCase()}?${params.toString()}`;
|
|
187
|
+
}
|
|
188
|
+
export function isBunkerUri(value) {
|
|
189
|
+
return value.trim().toLowerCase().startsWith('bunker://');
|
|
190
|
+
}
|
|
191
|
+
export function isNostrConnectUri(value) {
|
|
192
|
+
return value.trim().toLowerCase().startsWith('nostrconnect://');
|
|
193
|
+
}
|
|
194
|
+
export function isSupportedPairingUri(value) {
|
|
195
|
+
return isBunkerUri(value) || isNostrConnectUri(value);
|
|
196
|
+
}
|
|
152
197
|
/**
|
|
153
198
|
* Race a bunker handshake against a deadline. nostr-tools' `BunkerSigner`
|
|
154
199
|
* `sendRequest` has no per-request timeout — it publishes the request and only
|
|
@@ -177,11 +222,11 @@ async function raceBunkerHandshake(p, ms, bunker) {
|
|
|
177
222
|
}
|
|
178
223
|
}
|
|
179
224
|
/**
|
|
180
|
-
* Connect a bunker session from a `bunker://` or
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
225
|
+
* Connect a bunker session from a `bunker://` URI or NIP-05 identifier. Pass
|
|
226
|
+
* `clientSecretKey` to bind a stable client pubkey the signer can auto-approve
|
|
227
|
+
* (see `loadOrCreatePersistentClientSk`); when omitted a fresh ephemeral key is
|
|
228
|
+
* generated, which a per-pubkey-approving bunker will treat as a new,
|
|
229
|
+
* unapproved client.
|
|
185
230
|
*/
|
|
186
231
|
export async function createBunkerSigner(input) {
|
|
187
232
|
const trimmed = input.uri.trim();
|
package/dist/signet-login.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export type { NostrEvent, EventTemplate, LoginMethod, LoginPickerMethod, SignerCapabilities, SignetSigner, SignetAuthEvent, SignetSession, LoginOptions, RestoreOptions, SignetStorage, } from './types.js';
|
|
18
18
|
import type { SignetSigner, LoginOptions, RestoreOptions, SignetSession, SignetAuthEvent, SignetStorage } from './types.js';
|
|
19
|
-
import { hasNip07, createNip07Signer, createBunkerSigner, createBunkerSignerFromNostrConnect, buildNostrConnectUri, createLocalSignerFromNsec, generateSecretKey, Nip07Signer, BunkerSignerImpl, LocalSigner } from './signers.js';
|
|
19
|
+
import { hasNip07, createNip07Signer, createBunkerSigner, createBunkerSignerFromNostrConnect, buildNostrConnectUri, buildBunkerUriFromNostrConnectUri, isBunkerUri, isNostrConnectUri, isSupportedPairingUri, createLocalSignerFromNsec, generateSecretKey, Nip07Signer, BunkerSignerImpl, LocalSigner } from './signers.js';
|
|
20
20
|
import { type ConsumeAmberResult } from './amber.js';
|
|
21
21
|
import { handleCallback as handlePopupCallback } from './callback.js';
|
|
22
22
|
import type { ConsumeCallbackResult } from './redirect.js';
|
|
@@ -24,7 +24,7 @@ export type { CallbackResult } from './callback.js';
|
|
|
24
24
|
export type { ConsumeCallbackResult } from './redirect.js';
|
|
25
25
|
export type { ConsumeAmberResult } from './amber.js';
|
|
26
26
|
export { isAndroid } from './amber.js';
|
|
27
|
-
export { hasNip07, createNip07Signer, createBunkerSigner, createBunkerSignerFromNostrConnect, buildNostrConnectUri, createLocalSignerFromNsec, generateSecretKey, Nip07Signer, BunkerSignerImpl, LocalSigner, };
|
|
27
|
+
export { hasNip07, createNip07Signer, createBunkerSigner, createBunkerSignerFromNostrConnect, buildNostrConnectUri, buildBunkerUriFromNostrConnectUri, isBunkerUri, isNostrConnectUri, isSupportedPairingUri, createLocalSignerFromNsec, generateSecretKey, Nip07Signer, BunkerSignerImpl, LocalSigner, };
|
|
28
28
|
export interface HandleRedirectCallbackOptions {
|
|
29
29
|
/**
|
|
30
30
|
* Await the returned `bunker://` handoff before resolving the callback.
|