nostr-bray 2.3.0 → 3.0.0

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.
@@ -1,34 +1,33 @@
1
- import type { Event as NostrEvent } from 'nostr-tools';
1
+ import type { GetBalanceResult, NwcRequestOptions, NwcTransaction, NwcTransport, PayInvoiceResult } from '@forgesworn/nwc-kit';
2
2
  import type { SigningContext } from '../signing-context.js';
3
3
  import type { RelayPool } from '../relay-pool.js';
4
- import type { PublishResult } from '../types.js';
5
4
  /**
6
5
  * Load the wallets map from the JSON file. Returns empty map if file missing.
7
6
  *
8
7
  * @param walletsFile - Absolute path to the JSON wallets store.
9
- * @returns A map of public key hex strings to NWC URIs.
8
+ * @returns A map of public key hex strings to absolute NWC secret-file paths.
10
9
  *
11
10
  * @example
12
11
  * const wallets = loadWallets('/home/user/.bray/wallets.json')
13
- * // { 'abc123...': 'nostr+walletconnect://...' }
12
+ * // { 'abc123...': '/run/secrets/alice-nwc' }
14
13
  */
15
14
  export declare function loadWallets(walletsFile: string): Record<string, string>;
16
15
  /**
17
16
  * Save the wallets map to the JSON file. Creates parent dirs and sets 0600.
18
17
  *
19
18
  * @param walletsFile - Absolute path to the JSON wallets store.
20
- * @param wallets - Map of public key hex strings to NWC URIs to persist.
19
+ * @param wallets - Map of public key hex strings to absolute NWC secret-file paths.
21
20
  * @returns void
22
21
  *
23
22
  * @example
24
23
  * saveWallets('/home/user/.bray/wallets.json', {
25
- * 'abc123...': 'nostr+walletconnect://pubkey?relay=wss://relay.example&secret=deadbeef',
24
+ * 'abc123...': '/run/secrets/alice-nwc',
26
25
  * })
27
26
  */
28
27
  export declare function saveWallets(walletsFile: string, wallets: Record<string, string>): void;
29
28
  /**
30
29
  * Resolve the NWC URI for the active identity.
31
- * 1. Per-identity wallet from wallets file
30
+ * 1. Per-identity NWC secret file referenced by the wallet registry
32
31
  * 2. Global NWC URI (fallback)
33
32
  * 3. undefined (no wallet configured)
34
33
  *
@@ -37,27 +36,28 @@ export declare function saveWallets(walletsFile: string, wallets: Record<string,
37
36
  * @returns The resolved NWC URI, or `undefined` if no wallet is configured.
38
37
  *
39
38
  * @example
40
- * const uri = resolveNwcUri(ctx, '/home/user/.bray/wallets.json', process.env.NWC_URI)
39
+ * const uri = resolveNwcUri(ctx, '/home/user/.bray/wallets.json', configuredNwcUri)
41
40
  * if (!uri) throw new Error('No wallet configured')
42
41
  */
43
42
  export declare function resolveNwcUri(ctx: SigningContext, walletsFile: string, globalNwcUri?: string): string | undefined;
44
43
  export interface NwcConnection {
45
44
  pubkey: string;
46
45
  relay: string;
47
- secret: string;
46
+ relays: readonly string[];
47
+ lud16?: string;
48
48
  }
49
49
  /**
50
50
  * Parse a nostr+walletconnect:// URI.
51
51
  *
52
52
  * @param uri - A `nostr+walletconnect://` URI as specified in NIP-47.
53
- * @returns A parsed {@link NwcConnection} containing the wallet pubkey, relay URL, and connection secret.
54
- * @throws {Error} If `pubkey`, `relay`, or `secret` are missing from the URI.
53
+ * @returns Public connection metadata. The connection secret is never returned.
54
+ * @throws {Error} If the URI is malformed or insecure.
55
55
  *
56
56
  * @example
57
57
  * const conn = parseNwcUri(
58
58
  * 'nostr+walletconnect://abc123?relay=wss%3A%2F%2Frelay.example&secret=deadbeef',
59
59
  * )
60
- * // { pubkey: 'abc123', relay: 'wss://relay.example', secret: 'deadbeef' }
60
+ * // { pubkey: 'abc123', relay: 'wss://relay.example/', relays: ['wss://relay.example/'] }
61
61
  */
62
62
  export declare function parseNwcUri(uri: string): NwcConnection;
63
63
  export interface ZapReceipt {
@@ -87,9 +87,8 @@ export declare function handleZapReceipts(ctx: SigningContext, pool: RelayPool,
87
87
  * Decode basic bolt11 invoice fields.
88
88
  *
89
89
  * @param bolt11 - A BOLT-11 Lightning invoice string (e.g. `lnbc...`).
90
- * @returns An object with the decoded fields. `amountMsats` is present when the
91
- * amount is encoded in the invoice prefix; `description` and `expiry` are not
92
- * yet decoded and will be absent in the current implementation.
90
+ * @returns The bounded amount, description and expiry fields committed by the
91
+ * invoice. `amountMsats` is absent for an amountless invoice.
93
92
  *
94
93
  * @example
95
94
  * const { amountMsats } = handleZapDecode('lnbc1000n1...')
@@ -100,142 +99,47 @@ export declare function handleZapDecode(bolt11: string): {
100
99
  description?: string;
101
100
  expiry?: number;
102
101
  };
103
- /**
104
- * Pay a Lightning invoice via NWC.
105
- *
106
- * @param args - Payment arguments.
107
- * @param args.invoice - BOLT-11 Lightning invoice to pay.
108
- * @param args.nwcUri - NWC URI identifying the wallet to use.
109
- * @returns The signed NIP-47 request event and relay publish result.
110
- * @throws {Error} If `nwcUri` is not provided.
111
- *
112
- * @example
113
- * const { event, publish } = await handleZapSend(ctx, pool, {
114
- * invoice: 'lnbc500n1...',
115
- * nwcUri: 'nostr+walletconnect://abc123?relay=wss%3A%2F%2Frelay.example&secret=deadbeef',
116
- * })
117
- */
118
- export declare function handleZapSend(ctx: SigningContext, pool: RelayPool, args: {
119
- invoice: string;
120
- nwcUri?: string;
121
- }): Promise<{
122
- event: NostrEvent;
123
- publish: PublishResult;
124
- }>;
125
- /**
126
- * Request wallet balance via NWC.
127
- *
128
- * @param args - Balance request arguments.
129
- * @param args.nwcUri - NWC URI identifying the wallet to query.
130
- * @returns The signed NIP-47 `get_balance` request event and relay publish result.
131
- * @throws {Error} If `nwcUri` is not provided.
132
- *
133
- * @example
134
- * const { event, publish } = await handleZapBalance(ctx, pool, {
135
- * nwcUri: 'nostr+walletconnect://abc123?relay=wss%3A%2F%2Frelay.example&secret=deadbeef',
136
- * })
137
- */
138
- export declare function handleZapBalance(ctx: SigningContext, pool: RelayPool, args: {
102
+ interface NwcOperationOptions extends NwcRequestOptions {
103
+ /** Injectable for deterministic tests and specialised relay transports. */
104
+ transport?: NwcTransport;
105
+ }
106
+ interface NwcArgs extends NwcOperationOptions {
139
107
  nwcUri?: string;
140
- }): Promise<{
141
- event: NostrEvent;
142
- publish: PublishResult;
143
- }>;
108
+ }
109
+ export interface ZapPaymentResult extends PayInvoiceResult {
110
+ paymentHash: string;
111
+ verified: true;
112
+ }
144
113
  /**
145
- * Generate a Lightning invoice via NWC.
146
- *
147
- * @param args - Invoice creation arguments.
148
- * @param args.amountMsats - Invoice amount in millisatoshis.
149
- * @param args.description - Optional human-readable memo attached to the invoice.
150
- * @param args.nwcUri - NWC URI identifying the wallet to use.
151
- * @returns The signed NIP-47 `make_invoice` request event and relay publish result.
152
- * @throws {Error} If `nwcUri` is not provided.
153
- *
154
- * @example
155
- * const { event, publish } = await handleZapMakeInvoice(ctx, pool, {
156
- * amountMsats: 21_000,
157
- * description: 'Coffee ☕',
158
- * nwcUri: 'nostr+walletconnect://abc123?relay=wss%3A%2F%2Frelay.example&secret=deadbeef',
159
- * })
114
+ * The wallet may have submitted a payment but Bray cannot prove settlement.
115
+ * Callers must reconcile `paymentHash` before attempting the invoice again.
160
116
  */
161
- export declare function handleZapMakeInvoice(ctx: SigningContext, pool: RelayPool, args: {
117
+ export declare class ZapPaymentOutcomeUnknownError extends Error {
118
+ readonly paymentHash: string;
119
+ readonly code = "PAYMENT_OUTCOME_UNKNOWN";
120
+ constructor(paymentHash: string);
121
+ }
122
+ /** Pay a BOLT-11 invoice and return only after the wallet proves settlement. */
123
+ export declare function handleZapSend(_ctx: SigningContext, _pool: RelayPool, args: {
124
+ invoice: string;
125
+ } & NwcArgs): Promise<ZapPaymentResult>;
126
+ /** Return the wallet's confirmed balance in millisatoshis. */
127
+ export declare function handleZapBalance(_ctx: SigningContext, _pool: RelayPool, args: NwcArgs): Promise<GetBalanceResult>;
128
+ /** Generate a Lightning invoice through the configured wallet. */
129
+ export declare function handleZapMakeInvoice(_ctx: SigningContext, _pool: RelayPool, args: {
162
130
  amountMsats: number;
163
131
  description?: string;
164
- nwcUri?: string;
165
- }): Promise<{
166
- event: NostrEvent;
167
- publish: PublishResult;
168
- }>;
169
- /**
170
- * Look up an invoice via NWC.
171
- *
172
- * @param args - Lookup arguments. Provide at least one of `paymentHash` or `invoice`.
173
- * @param args.paymentHash - Hex-encoded payment hash of the invoice to look up.
174
- * @param args.invoice - BOLT-11 invoice string to look up.
175
- * @param args.nwcUri - NWC URI identifying the wallet to query.
176
- * @returns The signed NIP-47 `lookup_invoice` request event and relay publish result.
177
- * @throws {Error} If `nwcUri` is not provided.
178
- *
179
- * @example
180
- * const { event, publish } = await handleZapLookupInvoice(ctx, pool, {
181
- * paymentHash: 'a1b2c3...',
182
- * nwcUri: 'nostr+walletconnect://abc123?relay=wss%3A%2F%2Frelay.example&secret=deadbeef',
183
- * })
184
- */
185
- export declare function handleZapLookupInvoice(ctx: SigningContext, pool: RelayPool, args: {
132
+ } & NwcArgs): Promise<NwcTransaction>;
133
+ /** Look up an invoice and return the wallet's authenticated result. */
134
+ export declare function handleZapLookupInvoice(_ctx: SigningContext, _pool: RelayPool, args: {
186
135
  paymentHash?: string;
187
136
  invoice?: string;
188
- nwcUri?: string;
189
- }): Promise<{
190
- event: NostrEvent;
191
- publish: PublishResult;
192
- }>;
193
- /**
194
- * List recent transactions via NWC.
195
- *
196
- * @param args - Pagination arguments.
197
- * @param args.limit - Maximum number of transactions to return (default 10).
198
- * @param args.offset - Number of transactions to skip for pagination (default 0).
199
- * @param args.nwcUri - NWC URI identifying the wallet to query.
200
- * @returns The signed NIP-47 `list_transactions` request event and relay publish result.
201
- * @throws {Error} If `nwcUri` is not provided.
202
- *
203
- * @example
204
- * const { event, publish } = await handleZapListTransactions(ctx, pool, {
205
- * limit: 5,
206
- * offset: 0,
207
- * nwcUri: 'nostr+walletconnect://abc123?relay=wss%3A%2F%2Frelay.example&secret=deadbeef',
208
- * })
209
- */
210
- export declare function handleZapListTransactions(ctx: SigningContext, pool: RelayPool, args: {
137
+ } & NwcArgs): Promise<NwcTransaction>;
138
+ /** List recent transactions through the isolated NIP-47 extension 05 client. */
139
+ export declare function handleZapListTransactions(_ctx: SigningContext, _pool: RelayPool, args: {
211
140
  limit?: number;
212
141
  offset?: number;
213
- nwcUri?: string;
214
- }): Promise<{
215
- event: NostrEvent;
216
- publish: PublishResult;
142
+ } & NwcArgs): Promise<{
143
+ transactions: NwcTransaction[];
217
144
  }>;
218
- /**
219
- * Parse a NWC wallet response event.
220
- *
221
- * @param nwcUri - The NWC URI whose secret is used to decrypt the response.
222
- * @param event - A kind 23195 NIP-47 response event from the wallet service.
223
- * @returns The decrypted response payload containing `result_type`, an optional
224
- * `result` object, and an optional `error` with `code` and `message`.
225
- *
226
- * @example
227
- * const response = handleZapParseResponse(
228
- * 'nostr+walletconnect://abc123?relay=wss%3A%2F%2Frelay.example&secret=deadbeef',
229
- * walletResponseEvent,
230
- * )
231
- * if (response.error) console.error(response.error.message)
232
- * else console.log(response.result)
233
- */
234
- export declare function handleZapParseResponse(nwcUri: string, event: NostrEvent): {
235
- result_type: string;
236
- result?: Record<string, unknown>;
237
- error?: {
238
- code: string;
239
- message: string;
240
- };
241
- };
145
+ export {};