thunder-bridge 1.1.0 → 1.4.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.
- package/README.md +115 -6
- package/dist/index.cjs +1677 -1301
- package/dist/index.d.cts +217 -166
- package/dist/index.d.ts +217 -166
- package/dist/index.js +1673 -1300
- package/dist/{rail-Dp8bs6uZ.d.cts → rail-CqUfuYXJ.d.cts} +176 -9
- package/dist/{rail-Dp8bs6uZ.d.ts → rail-CqUfuYXJ.d.ts} +176 -9
- package/dist/server.cjs +1003 -381
- package/dist/server.d.cts +79 -37
- package/dist/server.d.ts +79 -37
- package/dist/server.js +991 -380
- package/openapi.yaml +1 -1
- package/package.json +33 -13
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
type Resolved = {
|
|
2
|
+
address: string;
|
|
3
|
+
bolt11: string;
|
|
4
|
+
verifyUrl: string;
|
|
5
|
+
paymentHash: string;
|
|
6
|
+
expiresAt: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Bech32-encode a pay endpoint as the `LNURL1` string LUD-01 defines, uppercase
|
|
10
|
+
* because that is the form it asks a QR to carry. An onion endpoint is http
|
|
11
|
+
* rather than https, which LUD-17 spells out, so both are taken here
|
|
12
|
+
*/
|
|
13
|
+
declare function toLnurl(endpoint: string): string;
|
|
14
|
+
|
|
1
15
|
/** Where a payment stands, `paid` is the only status that carries a preimage */
|
|
2
16
|
type PaymentStatus = "pending" | "paid" | "expired";
|
|
3
17
|
/** Whether the gateway resolved the address and got the invoice, or was handed one to watch */
|
|
@@ -75,9 +89,32 @@ interface WatchPaymentParams {
|
|
|
75
89
|
verifyUrl: string;
|
|
76
90
|
expiresAt: number;
|
|
77
91
|
trigger?: string;
|
|
92
|
+
/**
|
|
93
|
+
* How many of this trigger's settlements the gateway keeps replayable past the
|
|
94
|
+
* hour it would otherwise forget them in, up to the ceiling its operator set.
|
|
95
|
+
* Needs `trigger`, defaults to none
|
|
96
|
+
*/
|
|
97
|
+
replay?: number;
|
|
78
98
|
sealed?: string;
|
|
79
99
|
webhookUrl?: string;
|
|
80
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* A one minute pass onto one trigger's stream. It opens that trigger and nothing
|
|
103
|
+
* else, which is what makes it the thing to hand a browser when the trigger
|
|
104
|
+
* secret is not. `expiresAt` is unix seconds, like every other time here
|
|
105
|
+
*/
|
|
106
|
+
interface SocketTicket {
|
|
107
|
+
ticket: string;
|
|
108
|
+
expiresAt: number;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Which trigger the ticket opens, and how many of its settlements the socket
|
|
112
|
+
* replays on connect, up to the ceiling the gateway's operator set
|
|
113
|
+
*/
|
|
114
|
+
interface SocketTicketParams {
|
|
115
|
+
trigger: string;
|
|
116
|
+
replay?: number;
|
|
117
|
+
}
|
|
81
118
|
/** Why one wallet in the list could not be used */
|
|
82
119
|
type WalletReason = "address-unusable" | "unreachable" | "amount-not-accepted" | "cannot-prove-delivery" | "invoice-refused";
|
|
83
120
|
interface WalletFailure {
|
|
@@ -147,10 +184,22 @@ interface CreateOptions {
|
|
|
147
184
|
* from any URL a payer sees
|
|
148
185
|
*/
|
|
149
186
|
trigger?: string;
|
|
187
|
+
/**
|
|
188
|
+
* How many of the trigger's settlements the gateway keeps replayable past the
|
|
189
|
+
* hour it would otherwise forget them in, up to the ceiling its operator set.
|
|
190
|
+
* Needs `trigger`, defaults to none
|
|
191
|
+
*/
|
|
192
|
+
replay?: number;
|
|
150
193
|
}
|
|
151
194
|
interface FollowOptions {
|
|
152
195
|
/** Called for the recent settlements replayed on connect, then for each new one */
|
|
153
196
|
onPayment: (settled: TriggerEvent) => void;
|
|
197
|
+
/**
|
|
198
|
+
* How many settlements to ask for on connect, defaults to the gateway's ten.
|
|
199
|
+
* It hands back what it still holds, which is the last hour unless the
|
|
200
|
+
* payments were minted with `replay`
|
|
201
|
+
*/
|
|
202
|
+
replay?: number;
|
|
154
203
|
/** Called when a connection drops or a frame is refused, the follow keeps going */
|
|
155
204
|
onError?: (error: unknown) => void;
|
|
156
205
|
/** Reconnect after a drop, defaults to true */
|
|
@@ -294,8 +343,17 @@ declare class ThunderBridge {
|
|
|
294
343
|
* is called. A trigger has no terminal state, so this never resolves
|
|
295
344
|
*/
|
|
296
345
|
followTrigger(secret: string, options: FollowOptions): () => void;
|
|
346
|
+
/**
|
|
347
|
+
* A one minute pass onto one trigger's stream, for something that must hold
|
|
348
|
+
* neither the token nor the trigger secret. Mint it in a handler and answer
|
|
349
|
+
* with the ticket alone, because that is all a browser needs to connect and
|
|
350
|
+
* all it can do anything with. `watchTicketEndpoint` is this method already
|
|
351
|
+
* wrapped in a route
|
|
352
|
+
*/
|
|
353
|
+
createSocketTicket(params: SocketTicketParams): Promise<SocketTicket>;
|
|
297
354
|
private needsTicket;
|
|
298
355
|
private wsTicket;
|
|
356
|
+
private mintedTicket;
|
|
299
357
|
private sending;
|
|
300
358
|
private reading;
|
|
301
359
|
private speaking;
|
|
@@ -303,19 +361,87 @@ declare class ThunderBridge {
|
|
|
303
361
|
private checked;
|
|
304
362
|
}
|
|
305
363
|
|
|
306
|
-
|
|
307
|
-
|
|
364
|
+
/** A wallet reachable over NIP-47, as its `nostr+walletconnect://` URI describes it */
|
|
365
|
+
interface NwcConnection {
|
|
366
|
+
/** The wallet service's public key, which is what its answers have to be signed by */
|
|
367
|
+
walletPubkey: string;
|
|
368
|
+
/** Where to reach it, tried in order until one answers */
|
|
369
|
+
relays: string[];
|
|
370
|
+
/** Our own private key on this connection, and the only thing that authorises it */
|
|
371
|
+
secret: string;
|
|
372
|
+
}
|
|
373
|
+
/** A minted invoice and everything needed to watch it */
|
|
374
|
+
interface NwcInvoice {
|
|
308
375
|
bolt11: string;
|
|
309
|
-
verifyUrl: string;
|
|
310
376
|
paymentHash: string;
|
|
311
377
|
expiresAt: number;
|
|
312
|
-
}
|
|
378
|
+
}
|
|
379
|
+
interface NwcVerifyConfig {
|
|
380
|
+
/** The wallet this endpoint speaks for. It never leaves this process */
|
|
381
|
+
connection: NwcConnection;
|
|
382
|
+
/** The secret the payment hash was sealed with, and nothing else uses it */
|
|
383
|
+
secret: string;
|
|
384
|
+
/** How often the gateway should ask, in seconds, sent as `Cache-Control: max-age`, `5` by default */
|
|
385
|
+
pollEverySecs?: number;
|
|
386
|
+
/** How long one `lookup_invoice` may take before the wallet counts as unreachable, `10_000` by default */
|
|
387
|
+
askTimeoutMs?: number;
|
|
388
|
+
}
|
|
313
389
|
/**
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* rather than https, which LUD-17 spells out, so both are taken here
|
|
390
|
+
* Read a `nostr+walletconnect://` URI. Refuses a relay that is not `wss`, for the
|
|
391
|
+
* reason the gateway refuses a verify URL that is not https
|
|
317
392
|
*/
|
|
318
|
-
declare function
|
|
393
|
+
declare function nwcConnection(uri: string): NwcConnection;
|
|
394
|
+
/** Mint an invoice on the connected wallet, decoded so the caller need not trust its word */
|
|
395
|
+
declare function nwcInvoice(connection: NwcConnection, amountMsat: number, description: string, timeoutMs?: number): Promise<NwcInvoice>;
|
|
396
|
+
/**
|
|
397
|
+
* Mint a hold invoice on a hash the wallet does not hold the preimage for, which
|
|
398
|
+
* is what lets an operator be paid only by paying somebody else first. The hash
|
|
399
|
+
* has to come from the recipient's own invoice, and the invoice that comes back
|
|
400
|
+
* is decoded rather than believed
|
|
401
|
+
*/
|
|
402
|
+
declare function nwcHoldInvoice(connection: NwcConnection, held: {
|
|
403
|
+
paymentHash: string;
|
|
404
|
+
amountMsat: number;
|
|
405
|
+
description: string;
|
|
406
|
+
expirySecs: number;
|
|
407
|
+
minCltvExpiryDelta?: number;
|
|
408
|
+
}, timeoutMs?: number): Promise<NwcInvoice>;
|
|
409
|
+
/**
|
|
410
|
+
* The preimage the wallet released for this hash, null while it has released
|
|
411
|
+
* none. A preimage that does not hash to what was asked for is a lie rather than
|
|
412
|
+
* an answer, so it throws instead of being passed on
|
|
413
|
+
*/
|
|
414
|
+
declare function nwcSettlement(connection: NwcConnection, paymentHash: string, timeoutMs?: number): Promise<string | null>;
|
|
415
|
+
/**
|
|
416
|
+
* Pay an invoice and keep the preimage the network handed back. Whoever pays
|
|
417
|
+
* learns it, which is what makes delivery provable to a recipient publishing no
|
|
418
|
+
* LUD-21 of their own. A preimage that does not hash to the invoice's own hash is
|
|
419
|
+
* a lie rather than a receipt, so it throws instead of being passed on
|
|
420
|
+
*/
|
|
421
|
+
declare function nwcPay(connection: NwcConnection, bolt11: string, timeoutMs?: number): Promise<string>;
|
|
422
|
+
/**
|
|
423
|
+
* A verify endpoint of your own that asks your wallet over NIP-47, so the gateway
|
|
424
|
+
* polls you and never learns the connection, the relay, or which wallet it is.
|
|
425
|
+
*
|
|
426
|
+
* `nwcVerifyUrl` seals the payment hash into the query with your secret, which is
|
|
427
|
+
* what stops a stranger driving your wallet through this handler. It answers the
|
|
428
|
+
* LUD-21 shape the gateway already speaks, so nothing on that side changes.
|
|
429
|
+
*
|
|
430
|
+
* A wallet it cannot reach answers `502` rather than "not settled", because those
|
|
431
|
+
* are different claims and only one of them is true.
|
|
432
|
+
*/
|
|
433
|
+
declare function nwcVerifyEndpoint(config: NwcVerifyConfig): (request: Request) => Promise<Response>;
|
|
434
|
+
/**
|
|
435
|
+
* The URL to hand the gateway, with the payment hash sealed inside it. Point it at
|
|
436
|
+
* wherever `nwcVerifyEndpoint` is mounted
|
|
437
|
+
*/
|
|
438
|
+
declare function nwcVerifyUrl(endpoint: string, paymentHash: string, secret: string): Promise<string>;
|
|
439
|
+
/**
|
|
440
|
+
* One NIP-47 call, for a method this SDK does not wrap. The wallet's own info
|
|
441
|
+
* event lists what it will answer, and anything it refuses comes back as a
|
|
442
|
+
* `WalletRefused` carrying the code it named
|
|
443
|
+
*/
|
|
444
|
+
declare function askWallet(connection: NwcConnection, method: string, params: Record<string, unknown>, timeoutMs?: number): Promise<Record<string, unknown>>;
|
|
319
445
|
|
|
320
446
|
/** What a shop knows about a sale before any rail exists */
|
|
321
447
|
interface Order {
|
|
@@ -360,6 +486,8 @@ interface BankRailConfig {
|
|
|
360
486
|
expiresAt: (order: Order) => number;
|
|
361
487
|
/** Groups every leg on the same secret, so one `followTrigger` socket hears them all */
|
|
362
488
|
trigger?: string;
|
|
489
|
+
/** How many settlements of that trigger the gateway keeps replayable past the hour, needs `trigger` */
|
|
490
|
+
replay?: number;
|
|
363
491
|
/** Handed back untouched on that stream. Stable across re-offers, for the reason `expiresAt` is */
|
|
364
492
|
sealed?: (order: Order) => string | Promise<string>;
|
|
365
493
|
/** Up to ten digits, for accounting systems that still want one */
|
|
@@ -379,6 +507,8 @@ interface LightningRailConfig {
|
|
|
379
507
|
amountMsat: (order: Order) => number | Promise<number>;
|
|
380
508
|
/** Groups every leg on the same secret, so one `followTrigger` socket hears them all */
|
|
381
509
|
trigger?: string;
|
|
510
|
+
/** How many settlements of that trigger the gateway keeps replayable past the hour, needs `trigger` */
|
|
511
|
+
replay?: number;
|
|
382
512
|
/**
|
|
383
513
|
* Makes the mint safe to retry. Unset nothing is sent, because a key stable
|
|
384
514
|
* across re-offers is one the gateway can join against the bank leg's reference
|
|
@@ -397,6 +527,8 @@ interface BlindLightningRailConfig {
|
|
|
397
527
|
amountMsat: (order: Order) => number | Promise<number>;
|
|
398
528
|
/** Groups every leg on the same secret, so one `followTrigger` socket hears them all */
|
|
399
529
|
trigger?: string;
|
|
530
|
+
/** How many settlements of that trigger the gateway keeps replayable past the hour, needs `trigger` */
|
|
531
|
+
replay?: number;
|
|
400
532
|
/** Only a watched leg has anywhere to carry this */
|
|
401
533
|
sealed?: (order: Order) => string | Promise<string>;
|
|
402
534
|
webhookUrl?: string;
|
|
@@ -413,6 +545,34 @@ interface BlindLightningRailConfig {
|
|
|
413
545
|
/** What `Leg.rail` reads, for a shop running more than one wallet */
|
|
414
546
|
name?: string;
|
|
415
547
|
}
|
|
548
|
+
interface NwcRailConfig {
|
|
549
|
+
/** The gateway that watches an invoice your own wallet minted */
|
|
550
|
+
gateway: ThunderBridge;
|
|
551
|
+
/** Your wallet over NIP-47, from `nwcConnection`. It never reaches the gateway */
|
|
552
|
+
connection: NwcConnection;
|
|
553
|
+
/** What this order costs in millisatoshi */
|
|
554
|
+
amountMsat: (order: Order) => number | Promise<number>;
|
|
555
|
+
/**
|
|
556
|
+
* Where your own `nwcVerifyEndpoint` is mounted, and the secret it unseals
|
|
557
|
+
* with. The gateway is handed this URL rather than a wallet's, so it polls you
|
|
558
|
+
* and learns neither the connection nor which wallet is behind it
|
|
559
|
+
*/
|
|
560
|
+
verifyThrough: {
|
|
561
|
+
endpoint: string;
|
|
562
|
+
secret: string;
|
|
563
|
+
};
|
|
564
|
+
/** What the payer reads on the invoice, and what your wallet files it under */
|
|
565
|
+
description?: (order: Order) => string;
|
|
566
|
+
/** Groups every leg on the same secret, so one `followTrigger` socket hears them all */
|
|
567
|
+
trigger?: string;
|
|
568
|
+
/** How many settlements of that trigger the gateway keeps replayable past the hour, needs `trigger` */
|
|
569
|
+
replay?: number;
|
|
570
|
+
/** Only a watched leg has anywhere to carry this */
|
|
571
|
+
sealed?: (order: Order) => string | Promise<string>;
|
|
572
|
+
webhookUrl?: string;
|
|
573
|
+
/** What `Leg.rail` reads, for a shop running more than one wallet */
|
|
574
|
+
name?: string;
|
|
575
|
+
}
|
|
416
576
|
/**
|
|
417
577
|
* Sell for a bank transfer. The money moves straight to your account and the
|
|
418
578
|
* gateway is told a hash, a URL and an expiry, never the amount or the reference.
|
|
@@ -434,6 +594,13 @@ declare function lightningRail(config: LightningRailConfig): Rail;
|
|
|
434
594
|
* refusing everyone.
|
|
435
595
|
*/
|
|
436
596
|
declare function blindLightningRail(config: BlindLightningRailConfig): Rail;
|
|
597
|
+
/**
|
|
598
|
+
* Sell for Lightning against a wallet of your own over NIP-47, for a wallet that
|
|
599
|
+
* has no LUD-21 address to be watched at. Your node mints the invoice and releases
|
|
600
|
+
* the preimage, so the proof comes from one hop nearer than any hosted address can
|
|
601
|
+
* manage, and the gateway sees a hash and a URL of yours.
|
|
602
|
+
*/
|
|
603
|
+
declare function nwcRail(config: NwcRailConfig): Rail;
|
|
437
604
|
/**
|
|
438
605
|
* A provable invoice from the first address on the list that will issue one, which
|
|
439
606
|
* is what a client mints for itself rather than asking a gateway to. Everything the
|
|
@@ -445,4 +612,4 @@ declare function blindLightningRail(config: BlindLightningRailConfig): Rail;
|
|
|
445
612
|
*/
|
|
446
613
|
declare function invoiceFrom(lnAddresses: string[], amountMsat: number): Promise<Resolved>;
|
|
447
614
|
|
|
448
|
-
export { type BankRailConfig as B, type CreatePaymentParams as C, type FollowOptions as F, type Leg as L, type Order as O, type Payment as P, type Quote as Q, type Rail as R, type Settlement as S, ThunderBridge as T, type
|
|
615
|
+
export { nwcPay as A, type BankRailConfig as B, type CreatePaymentParams as C, nwcRail as D, nwcSettlement as E, type FollowOptions as F, nwcVerifyEndpoint as G, nwcVerifyUrl as H, type Leg as L, type NwcConnection as N, type Order as O, type Payment as P, type Quote as Q, type Rail as R, type Settlement as S, ThunderBridge as T, type WalletFailure as W, type ThunderBridgeOptions as a, type WatchPaymentParams as b, type TriggerEvent as c, type WaitOptions as d, type CreateOptions as e, type CreateQuoteParams as f, type LightningRailConfig as g, type PaymentKind as h, type PaymentStatus as i, type SocketTicket as j, type SocketTicketParams as k, type WalletReason as l, bankRail as m, lightningRail as n, type BlindLightningRailConfig as o, type NwcInvoice as p, type NwcRailConfig as q, type NwcVerifyConfig as r, type Resolved as s, toLnurl as t, askWallet as u, blindLightningRail as v, invoiceFrom as w, nwcConnection as x, nwcHoldInvoice as y, nwcInvoice as z };
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
type Resolved = {
|
|
2
|
+
address: string;
|
|
3
|
+
bolt11: string;
|
|
4
|
+
verifyUrl: string;
|
|
5
|
+
paymentHash: string;
|
|
6
|
+
expiresAt: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Bech32-encode a pay endpoint as the `LNURL1` string LUD-01 defines, uppercase
|
|
10
|
+
* because that is the form it asks a QR to carry. An onion endpoint is http
|
|
11
|
+
* rather than https, which LUD-17 spells out, so both are taken here
|
|
12
|
+
*/
|
|
13
|
+
declare function toLnurl(endpoint: string): string;
|
|
14
|
+
|
|
1
15
|
/** Where a payment stands, `paid` is the only status that carries a preimage */
|
|
2
16
|
type PaymentStatus = "pending" | "paid" | "expired";
|
|
3
17
|
/** Whether the gateway resolved the address and got the invoice, or was handed one to watch */
|
|
@@ -75,9 +89,32 @@ interface WatchPaymentParams {
|
|
|
75
89
|
verifyUrl: string;
|
|
76
90
|
expiresAt: number;
|
|
77
91
|
trigger?: string;
|
|
92
|
+
/**
|
|
93
|
+
* How many of this trigger's settlements the gateway keeps replayable past the
|
|
94
|
+
* hour it would otherwise forget them in, up to the ceiling its operator set.
|
|
95
|
+
* Needs `trigger`, defaults to none
|
|
96
|
+
*/
|
|
97
|
+
replay?: number;
|
|
78
98
|
sealed?: string;
|
|
79
99
|
webhookUrl?: string;
|
|
80
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* A one minute pass onto one trigger's stream. It opens that trigger and nothing
|
|
103
|
+
* else, which is what makes it the thing to hand a browser when the trigger
|
|
104
|
+
* secret is not. `expiresAt` is unix seconds, like every other time here
|
|
105
|
+
*/
|
|
106
|
+
interface SocketTicket {
|
|
107
|
+
ticket: string;
|
|
108
|
+
expiresAt: number;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Which trigger the ticket opens, and how many of its settlements the socket
|
|
112
|
+
* replays on connect, up to the ceiling the gateway's operator set
|
|
113
|
+
*/
|
|
114
|
+
interface SocketTicketParams {
|
|
115
|
+
trigger: string;
|
|
116
|
+
replay?: number;
|
|
117
|
+
}
|
|
81
118
|
/** Why one wallet in the list could not be used */
|
|
82
119
|
type WalletReason = "address-unusable" | "unreachable" | "amount-not-accepted" | "cannot-prove-delivery" | "invoice-refused";
|
|
83
120
|
interface WalletFailure {
|
|
@@ -147,10 +184,22 @@ interface CreateOptions {
|
|
|
147
184
|
* from any URL a payer sees
|
|
148
185
|
*/
|
|
149
186
|
trigger?: string;
|
|
187
|
+
/**
|
|
188
|
+
* How many of the trigger's settlements the gateway keeps replayable past the
|
|
189
|
+
* hour it would otherwise forget them in, up to the ceiling its operator set.
|
|
190
|
+
* Needs `trigger`, defaults to none
|
|
191
|
+
*/
|
|
192
|
+
replay?: number;
|
|
150
193
|
}
|
|
151
194
|
interface FollowOptions {
|
|
152
195
|
/** Called for the recent settlements replayed on connect, then for each new one */
|
|
153
196
|
onPayment: (settled: TriggerEvent) => void;
|
|
197
|
+
/**
|
|
198
|
+
* How many settlements to ask for on connect, defaults to the gateway's ten.
|
|
199
|
+
* It hands back what it still holds, which is the last hour unless the
|
|
200
|
+
* payments were minted with `replay`
|
|
201
|
+
*/
|
|
202
|
+
replay?: number;
|
|
154
203
|
/** Called when a connection drops or a frame is refused, the follow keeps going */
|
|
155
204
|
onError?: (error: unknown) => void;
|
|
156
205
|
/** Reconnect after a drop, defaults to true */
|
|
@@ -294,8 +343,17 @@ declare class ThunderBridge {
|
|
|
294
343
|
* is called. A trigger has no terminal state, so this never resolves
|
|
295
344
|
*/
|
|
296
345
|
followTrigger(secret: string, options: FollowOptions): () => void;
|
|
346
|
+
/**
|
|
347
|
+
* A one minute pass onto one trigger's stream, for something that must hold
|
|
348
|
+
* neither the token nor the trigger secret. Mint it in a handler and answer
|
|
349
|
+
* with the ticket alone, because that is all a browser needs to connect and
|
|
350
|
+
* all it can do anything with. `watchTicketEndpoint` is this method already
|
|
351
|
+
* wrapped in a route
|
|
352
|
+
*/
|
|
353
|
+
createSocketTicket(params: SocketTicketParams): Promise<SocketTicket>;
|
|
297
354
|
private needsTicket;
|
|
298
355
|
private wsTicket;
|
|
356
|
+
private mintedTicket;
|
|
299
357
|
private sending;
|
|
300
358
|
private reading;
|
|
301
359
|
private speaking;
|
|
@@ -303,19 +361,87 @@ declare class ThunderBridge {
|
|
|
303
361
|
private checked;
|
|
304
362
|
}
|
|
305
363
|
|
|
306
|
-
|
|
307
|
-
|
|
364
|
+
/** A wallet reachable over NIP-47, as its `nostr+walletconnect://` URI describes it */
|
|
365
|
+
interface NwcConnection {
|
|
366
|
+
/** The wallet service's public key, which is what its answers have to be signed by */
|
|
367
|
+
walletPubkey: string;
|
|
368
|
+
/** Where to reach it, tried in order until one answers */
|
|
369
|
+
relays: string[];
|
|
370
|
+
/** Our own private key on this connection, and the only thing that authorises it */
|
|
371
|
+
secret: string;
|
|
372
|
+
}
|
|
373
|
+
/** A minted invoice and everything needed to watch it */
|
|
374
|
+
interface NwcInvoice {
|
|
308
375
|
bolt11: string;
|
|
309
|
-
verifyUrl: string;
|
|
310
376
|
paymentHash: string;
|
|
311
377
|
expiresAt: number;
|
|
312
|
-
}
|
|
378
|
+
}
|
|
379
|
+
interface NwcVerifyConfig {
|
|
380
|
+
/** The wallet this endpoint speaks for. It never leaves this process */
|
|
381
|
+
connection: NwcConnection;
|
|
382
|
+
/** The secret the payment hash was sealed with, and nothing else uses it */
|
|
383
|
+
secret: string;
|
|
384
|
+
/** How often the gateway should ask, in seconds, sent as `Cache-Control: max-age`, `5` by default */
|
|
385
|
+
pollEverySecs?: number;
|
|
386
|
+
/** How long one `lookup_invoice` may take before the wallet counts as unreachable, `10_000` by default */
|
|
387
|
+
askTimeoutMs?: number;
|
|
388
|
+
}
|
|
313
389
|
/**
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* rather than https, which LUD-17 spells out, so both are taken here
|
|
390
|
+
* Read a `nostr+walletconnect://` URI. Refuses a relay that is not `wss`, for the
|
|
391
|
+
* reason the gateway refuses a verify URL that is not https
|
|
317
392
|
*/
|
|
318
|
-
declare function
|
|
393
|
+
declare function nwcConnection(uri: string): NwcConnection;
|
|
394
|
+
/** Mint an invoice on the connected wallet, decoded so the caller need not trust its word */
|
|
395
|
+
declare function nwcInvoice(connection: NwcConnection, amountMsat: number, description: string, timeoutMs?: number): Promise<NwcInvoice>;
|
|
396
|
+
/**
|
|
397
|
+
* Mint a hold invoice on a hash the wallet does not hold the preimage for, which
|
|
398
|
+
* is what lets an operator be paid only by paying somebody else first. The hash
|
|
399
|
+
* has to come from the recipient's own invoice, and the invoice that comes back
|
|
400
|
+
* is decoded rather than believed
|
|
401
|
+
*/
|
|
402
|
+
declare function nwcHoldInvoice(connection: NwcConnection, held: {
|
|
403
|
+
paymentHash: string;
|
|
404
|
+
amountMsat: number;
|
|
405
|
+
description: string;
|
|
406
|
+
expirySecs: number;
|
|
407
|
+
minCltvExpiryDelta?: number;
|
|
408
|
+
}, timeoutMs?: number): Promise<NwcInvoice>;
|
|
409
|
+
/**
|
|
410
|
+
* The preimage the wallet released for this hash, null while it has released
|
|
411
|
+
* none. A preimage that does not hash to what was asked for is a lie rather than
|
|
412
|
+
* an answer, so it throws instead of being passed on
|
|
413
|
+
*/
|
|
414
|
+
declare function nwcSettlement(connection: NwcConnection, paymentHash: string, timeoutMs?: number): Promise<string | null>;
|
|
415
|
+
/**
|
|
416
|
+
* Pay an invoice and keep the preimage the network handed back. Whoever pays
|
|
417
|
+
* learns it, which is what makes delivery provable to a recipient publishing no
|
|
418
|
+
* LUD-21 of their own. A preimage that does not hash to the invoice's own hash is
|
|
419
|
+
* a lie rather than a receipt, so it throws instead of being passed on
|
|
420
|
+
*/
|
|
421
|
+
declare function nwcPay(connection: NwcConnection, bolt11: string, timeoutMs?: number): Promise<string>;
|
|
422
|
+
/**
|
|
423
|
+
* A verify endpoint of your own that asks your wallet over NIP-47, so the gateway
|
|
424
|
+
* polls you and never learns the connection, the relay, or which wallet it is.
|
|
425
|
+
*
|
|
426
|
+
* `nwcVerifyUrl` seals the payment hash into the query with your secret, which is
|
|
427
|
+
* what stops a stranger driving your wallet through this handler. It answers the
|
|
428
|
+
* LUD-21 shape the gateway already speaks, so nothing on that side changes.
|
|
429
|
+
*
|
|
430
|
+
* A wallet it cannot reach answers `502` rather than "not settled", because those
|
|
431
|
+
* are different claims and only one of them is true.
|
|
432
|
+
*/
|
|
433
|
+
declare function nwcVerifyEndpoint(config: NwcVerifyConfig): (request: Request) => Promise<Response>;
|
|
434
|
+
/**
|
|
435
|
+
* The URL to hand the gateway, with the payment hash sealed inside it. Point it at
|
|
436
|
+
* wherever `nwcVerifyEndpoint` is mounted
|
|
437
|
+
*/
|
|
438
|
+
declare function nwcVerifyUrl(endpoint: string, paymentHash: string, secret: string): Promise<string>;
|
|
439
|
+
/**
|
|
440
|
+
* One NIP-47 call, for a method this SDK does not wrap. The wallet's own info
|
|
441
|
+
* event lists what it will answer, and anything it refuses comes back as a
|
|
442
|
+
* `WalletRefused` carrying the code it named
|
|
443
|
+
*/
|
|
444
|
+
declare function askWallet(connection: NwcConnection, method: string, params: Record<string, unknown>, timeoutMs?: number): Promise<Record<string, unknown>>;
|
|
319
445
|
|
|
320
446
|
/** What a shop knows about a sale before any rail exists */
|
|
321
447
|
interface Order {
|
|
@@ -360,6 +486,8 @@ interface BankRailConfig {
|
|
|
360
486
|
expiresAt: (order: Order) => number;
|
|
361
487
|
/** Groups every leg on the same secret, so one `followTrigger` socket hears them all */
|
|
362
488
|
trigger?: string;
|
|
489
|
+
/** How many settlements of that trigger the gateway keeps replayable past the hour, needs `trigger` */
|
|
490
|
+
replay?: number;
|
|
363
491
|
/** Handed back untouched on that stream. Stable across re-offers, for the reason `expiresAt` is */
|
|
364
492
|
sealed?: (order: Order) => string | Promise<string>;
|
|
365
493
|
/** Up to ten digits, for accounting systems that still want one */
|
|
@@ -379,6 +507,8 @@ interface LightningRailConfig {
|
|
|
379
507
|
amountMsat: (order: Order) => number | Promise<number>;
|
|
380
508
|
/** Groups every leg on the same secret, so one `followTrigger` socket hears them all */
|
|
381
509
|
trigger?: string;
|
|
510
|
+
/** How many settlements of that trigger the gateway keeps replayable past the hour, needs `trigger` */
|
|
511
|
+
replay?: number;
|
|
382
512
|
/**
|
|
383
513
|
* Makes the mint safe to retry. Unset nothing is sent, because a key stable
|
|
384
514
|
* across re-offers is one the gateway can join against the bank leg's reference
|
|
@@ -397,6 +527,8 @@ interface BlindLightningRailConfig {
|
|
|
397
527
|
amountMsat: (order: Order) => number | Promise<number>;
|
|
398
528
|
/** Groups every leg on the same secret, so one `followTrigger` socket hears them all */
|
|
399
529
|
trigger?: string;
|
|
530
|
+
/** How many settlements of that trigger the gateway keeps replayable past the hour, needs `trigger` */
|
|
531
|
+
replay?: number;
|
|
400
532
|
/** Only a watched leg has anywhere to carry this */
|
|
401
533
|
sealed?: (order: Order) => string | Promise<string>;
|
|
402
534
|
webhookUrl?: string;
|
|
@@ -413,6 +545,34 @@ interface BlindLightningRailConfig {
|
|
|
413
545
|
/** What `Leg.rail` reads, for a shop running more than one wallet */
|
|
414
546
|
name?: string;
|
|
415
547
|
}
|
|
548
|
+
interface NwcRailConfig {
|
|
549
|
+
/** The gateway that watches an invoice your own wallet minted */
|
|
550
|
+
gateway: ThunderBridge;
|
|
551
|
+
/** Your wallet over NIP-47, from `nwcConnection`. It never reaches the gateway */
|
|
552
|
+
connection: NwcConnection;
|
|
553
|
+
/** What this order costs in millisatoshi */
|
|
554
|
+
amountMsat: (order: Order) => number | Promise<number>;
|
|
555
|
+
/**
|
|
556
|
+
* Where your own `nwcVerifyEndpoint` is mounted, and the secret it unseals
|
|
557
|
+
* with. The gateway is handed this URL rather than a wallet's, so it polls you
|
|
558
|
+
* and learns neither the connection nor which wallet is behind it
|
|
559
|
+
*/
|
|
560
|
+
verifyThrough: {
|
|
561
|
+
endpoint: string;
|
|
562
|
+
secret: string;
|
|
563
|
+
};
|
|
564
|
+
/** What the payer reads on the invoice, and what your wallet files it under */
|
|
565
|
+
description?: (order: Order) => string;
|
|
566
|
+
/** Groups every leg on the same secret, so one `followTrigger` socket hears them all */
|
|
567
|
+
trigger?: string;
|
|
568
|
+
/** How many settlements of that trigger the gateway keeps replayable past the hour, needs `trigger` */
|
|
569
|
+
replay?: number;
|
|
570
|
+
/** Only a watched leg has anywhere to carry this */
|
|
571
|
+
sealed?: (order: Order) => string | Promise<string>;
|
|
572
|
+
webhookUrl?: string;
|
|
573
|
+
/** What `Leg.rail` reads, for a shop running more than one wallet */
|
|
574
|
+
name?: string;
|
|
575
|
+
}
|
|
416
576
|
/**
|
|
417
577
|
* Sell for a bank transfer. The money moves straight to your account and the
|
|
418
578
|
* gateway is told a hash, a URL and an expiry, never the amount or the reference.
|
|
@@ -434,6 +594,13 @@ declare function lightningRail(config: LightningRailConfig): Rail;
|
|
|
434
594
|
* refusing everyone.
|
|
435
595
|
*/
|
|
436
596
|
declare function blindLightningRail(config: BlindLightningRailConfig): Rail;
|
|
597
|
+
/**
|
|
598
|
+
* Sell for Lightning against a wallet of your own over NIP-47, for a wallet that
|
|
599
|
+
* has no LUD-21 address to be watched at. Your node mints the invoice and releases
|
|
600
|
+
* the preimage, so the proof comes from one hop nearer than any hosted address can
|
|
601
|
+
* manage, and the gateway sees a hash and a URL of yours.
|
|
602
|
+
*/
|
|
603
|
+
declare function nwcRail(config: NwcRailConfig): Rail;
|
|
437
604
|
/**
|
|
438
605
|
* A provable invoice from the first address on the list that will issue one, which
|
|
439
606
|
* is what a client mints for itself rather than asking a gateway to. Everything the
|
|
@@ -445,4 +612,4 @@ declare function blindLightningRail(config: BlindLightningRailConfig): Rail;
|
|
|
445
612
|
*/
|
|
446
613
|
declare function invoiceFrom(lnAddresses: string[], amountMsat: number): Promise<Resolved>;
|
|
447
614
|
|
|
448
|
-
export { type BankRailConfig as B, type CreatePaymentParams as C, type FollowOptions as F, type Leg as L, type Order as O, type Payment as P, type Quote as Q, type Rail as R, type Settlement as S, ThunderBridge as T, type
|
|
615
|
+
export { nwcPay as A, type BankRailConfig as B, type CreatePaymentParams as C, nwcRail as D, nwcSettlement as E, type FollowOptions as F, nwcVerifyEndpoint as G, nwcVerifyUrl as H, type Leg as L, type NwcConnection as N, type Order as O, type Payment as P, type Quote as Q, type Rail as R, type Settlement as S, ThunderBridge as T, type WalletFailure as W, type ThunderBridgeOptions as a, type WatchPaymentParams as b, type TriggerEvent as c, type WaitOptions as d, type CreateOptions as e, type CreateQuoteParams as f, type LightningRailConfig as g, type PaymentKind as h, type PaymentStatus as i, type SocketTicket as j, type SocketTicketParams as k, type WalletReason as l, bankRail as m, lightningRail as n, type BlindLightningRailConfig as o, type NwcInvoice as p, type NwcRailConfig as q, type NwcVerifyConfig as r, type Resolved as s, toLnurl as t, askWallet as u, blindLightningRail as v, invoiceFrom as w, nwcConnection as x, nwcHoldInvoice as y, nwcInvoice as z };
|