thunder-bridge 2.1.1 → 2.2.1
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 +40 -17
- package/dist/{bank-M8flcMks.d.ts → bank-BgA45yOU.d.ts} +186 -18
- package/dist/{bank-CEIuNhV_.d.cts → bank-DvcV85sa.d.cts} +186 -18
- package/dist/bank.cjs +10 -4
- package/dist/bank.d.cts +8 -2
- package/dist/bank.d.ts +8 -2
- package/dist/bank.js +10 -4
- package/dist/{errors-DriqW-lp.d.cts → errors-DJmsalYZ.d.cts} +1 -1
- package/dist/{errors-ZEUT-MhO.d.ts → errors-VX0R18oE.d.ts} +1 -1
- package/dist/index.cjs +618 -91
- package/dist/index.d.cts +13 -4
- package/dist/index.d.ts +13 -4
- package/dist/index.js +617 -91
- package/dist/nwc.cjs +78 -21
- package/dist/nwc.d.cts +10 -113
- package/dist/nwc.d.ts +10 -113
- package/dist/nwc.js +78 -21
- package/dist/price.d.cts +1 -1
- package/dist/price.d.ts +1 -1
- package/openapi.yaml +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ so the same wallet on another domain can answer differently.
|
|
|
34
34
|
A refusal happens at creation rather than leaving a payment pending until a
|
|
35
35
|
watcher gives up, so a recipient finds out before a payer sees a QR code.
|
|
36
36
|
|
|
37
|
-
If your recipient is on a refused name, `
|
|
37
|
+
If your recipient is on a refused name, `gateway.rails.nwc` is the way round it: your own
|
|
38
38
|
wallet answers over NIP-47 instead of over an address, and the gateway watches the
|
|
39
39
|
hash exactly the same. [docs/lud21-coverage.md](../docs/lud21-coverage.md) is the
|
|
40
40
|
measured list rather than a reading of changelogs, last surveyed 2026-08-12. Read
|
|
@@ -137,27 +137,27 @@ preimage, and which side does the checking.
|
|
|
137
137
|
| the gateway is told | a hash, an expiry and your URL, with the wallet's sealed inside |
|
|
138
138
|
| the invoice is checked by | nobody needs to, you resolved the address yourself |
|
|
139
139
|
| the gateway probes first | `speaksVerify`: a GET on the URL, then a signed POST nonce it must echo |
|
|
140
|
-
| the gateway polls | your `serve.
|
|
140
|
+
| the gateway polls | your `serve.lightningVerify` endpoint, once `relayThrough` is set. Leave it off and the gateway polls the wallet directly, as on the minted rail |
|
|
141
141
|
| `settled` comes from | your endpoint, which unseals, asks the wallet and relays the answer |
|
|
142
142
|
| the pace is set by | you, `pollEverySecs` |
|
|
143
143
|
|
|
144
|
-
| `
|
|
144
|
+
| `rails.nwc` | your own wallet mints it, over NIP-47 `make_invoice` |
|
|
145
145
|
|---|---|
|
|
146
146
|
| the gateway is told | a hash and your URL, with the hash sealed inside |
|
|
147
147
|
| the invoice is checked by | nobody, it is your wallet |
|
|
148
148
|
| the gateway probes first | the same GET and signed nonce |
|
|
149
|
-
| the gateway polls | your `
|
|
149
|
+
| the gateway polls | your `serve.nwcVerify` endpoint |
|
|
150
150
|
| `settled` comes from | `lookup_invoice`, refused unless the wallet's own key signed it |
|
|
151
151
|
| the pace is set by | you, `pollEverySecs` |
|
|
152
152
|
|
|
153
153
|
| `rails.bank` | nobody, there is no invoice |
|
|
154
154
|
|---|---|
|
|
155
|
-
| the gateway is told | a hash and your URL,
|
|
155
|
+
| the gateway is told | a hash and your URL, whose query is one sealed blob naming neither the amount, the reference nor the account |
|
|
156
156
|
| the invoice is checked by | nobody, there is no invoice to check |
|
|
157
157
|
| the gateway probes first | the same GET and signed nonce |
|
|
158
158
|
| the gateway polls | your `serve.bankVerify` endpoint |
|
|
159
159
|
| `settled` comes from | a `Statement` credit matching amount and currency exactly, with the reference anywhere in the payer's text |
|
|
160
|
-
| the pace is set by |
|
|
160
|
+
| the pace is set by | the statement: `fioStatement` reads every thirty seconds divided by its tokens, and `pollEverySecs` overrides it |
|
|
161
161
|
|
|
162
162
|
Two things are worth reading off those blocks rather than inferring.
|
|
163
163
|
|
|
@@ -203,7 +203,7 @@ without saying whether either invoice was paid.
|
|
|
203
203
|
concluding the invoice went unpaid. The body still reads `settled: false`, and the
|
|
204
204
|
status is what separates "could not ask" from "asked, and no"
|
|
205
205
|
|
|
206
|
-
**`
|
|
206
|
+
**`rails.nwc`**
|
|
207
207
|
|
|
208
208
|
- an NWC connection to your own wallet, and the nostr relays behind it
|
|
209
209
|
- **scope the connection to `make_invoice` and `lookup_invoice`, never
|
|
@@ -268,7 +268,7 @@ Four sharp edges, worth reading before you build:
|
|
|
268
268
|
proving an invoice belongs to an address never proves the address belongs to
|
|
269
269
|
whoever you think it does.
|
|
270
270
|
|
|
271
|
-
`
|
|
271
|
+
`agreesWithItself` is the one to be careful with: it asks only whether a report holds
|
|
272
272
|
together, so a gateway that generates a preimage, hashes it and builds an invoice
|
|
273
273
|
around that hash passes it. If a payment matters, ask the recipient with
|
|
274
274
|
`prove` on the payment request or with `proveSettlement`. The full argument, including the five
|
|
@@ -308,13 +308,16 @@ const rail = gateway.rails.lightning({ paidTo: "iamfatik@blink.sv", amount: () =
|
|
|
308
308
|
`payments`, `settled`, `firstSettled`, `follow`, `ticket`, `nameFor` and
|
|
309
309
|
`webhookKey`, all on the instance
|
|
310
310
|
- **what you mount** is on `gateway.serve`: an LNURL-pay endpoint, the two ticket
|
|
311
|
-
endpoints, the verify endpoints
|
|
312
|
-
and the readers under it
|
|
311
|
+
endpoints, the verify endpoints `lightningVerify`, `bankVerify` and `nwcVerify`, the
|
|
312
|
+
webhook route, and the readers under it
|
|
313
313
|
- **one call per sale** is on `gateway.rails`: `lightning`, `blindLightning`,
|
|
314
|
-
`bank`, and `transfer` for a bank transfer on its own
|
|
314
|
+
`bank`, `nwc`, and `transfer` for a bank transfer on its own. What the NWC rail
|
|
315
|
+
needs to reach your wallet, `nwcConnection` and the wallet calls, stays in
|
|
316
|
+
`thunder-bridge/nwc`
|
|
315
317
|
- **the proofs** are free functions, deliberately, because a proof you cannot run
|
|
316
318
|
without the thing being audited is not a proof: `proveOrigin`, `proveSettlement`,
|
|
317
|
-
`proveWrapped`, `
|
|
319
|
+
`proveWrapped`, `decodeInvoice`, `preimageMatchesHash`. `agreesWithItself` sits
|
|
320
|
+
beside them and proves less, as the table below says
|
|
318
321
|
- **a payment reads without an assertion.** `Payment` is `MintedPayment |
|
|
319
322
|
WatchedPayment`, so checking `kind` is what makes the address, the amount and the
|
|
320
323
|
invoice non-null. The gateway writes those three together or writes none of them,
|
|
@@ -324,6 +327,20 @@ const rail = gateway.rails.lightning({ paidTo: "iamfatik@blink.sv", amount: () =
|
|
|
324
327
|
What your service answers once those handlers are mounted is written out in
|
|
325
328
|
[`openapi.yaml`](openapi.yaml), shipped with this package.
|
|
326
329
|
|
|
330
|
+
### Which call checks what
|
|
331
|
+
|
|
332
|
+
There are several ways to hear that a payment settled because there are several
|
|
333
|
+
places to hear it from. They do not check the same thing, and the difference is
|
|
334
|
+
what you may act on without asking anyone else.
|
|
335
|
+
|
|
336
|
+
| You hear it through | What the claim is checked against |
|
|
337
|
+
| --- | --- |
|
|
338
|
+
| `payment`, `settled`, `firstSettled`, `paid()` on a `requestPayment`, and `Gateways.settled` | the `{ id, paymentHash }` you hold. Another payment, another hash, or a preimage that does not hash to yours throws `GatewayCheatError` |
|
|
339
|
+
| `serve.webhook`, `serve.readSettlement`, `serve.readPayment` | the gateway's key, the timestamp, the URL it was sent to, and the preimage against the hash in the same body. Find your order by that hash before you act, which is what makes a pair the gateway invented find nothing |
|
|
340
|
+
| `payments`, `follow` | the report itself. An entry claiming paid whose preimage does not hash to its own hash is left out of `payments` and reaches `follow`'s `onError` rather than `onPayment` |
|
|
341
|
+
| `agreesWithItself` | the report itself, and nothing you hold, so a gateway that invents a preimage and names its hash passes it |
|
|
342
|
+
| `proveSettlement` | the recipient's own verify URL, after the origin proof, so the gateway is not asked at all |
|
|
343
|
+
|
|
327
344
|
## Errors
|
|
328
345
|
|
|
329
346
|
Every failure from the gateway is an RFC 9457 problem document. Branch on `type`,
|
|
@@ -400,10 +417,16 @@ try {
|
|
|
400
417
|
|
|
401
418
|
Pass `webhookUrl` when you create a payment, or on any rail. There is no webhook
|
|
402
419
|
secret: a gateway holds nothing of yours, and sending one is refused rather than
|
|
403
|
-
ignored. Every delivery
|
|
404
|
-
publishes at `/webhook-key`, over `<x-timestamp
|
|
405
|
-
|
|
406
|
-
at
|
|
420
|
+
ignored. Every delivery carries `x-signature-v2: ed25519=<signature>` with the key
|
|
421
|
+
the gateway publishes at `/webhook-key`, over the URL it was sent to, `<x-timestamp>`
|
|
422
|
+
and the raw body, so a delivery made for somebody else's endpoint proves nothing at
|
|
423
|
+
yours and a captured one cannot be replayed at you later. Behind a proxy that hands
|
|
424
|
+
the request on under another host or scheme, pass the URL you registered as `url`.
|
|
425
|
+
Until then
|
|
426
|
+
`serve.webhook` acts on each settlement once, answering a replay `200` without
|
|
427
|
+
calling you again. Delivery is still at-least-once: a retry after that window, or
|
|
428
|
+
one reaching another instance of your server, calls you again, so fulfil
|
|
429
|
+
idempotently on `id`.
|
|
407
430
|
|
|
408
431
|
Your handler answers one challenge before any of that. The gateway POSTs
|
|
409
432
|
`{"type":"webhook-challenge","nonce":"..."}` to the URL while the create is still
|
|
@@ -431,7 +454,7 @@ that proves nothing gets a `202` and no callback, because acting on an unproven
|
|
|
431
454
|
claim is the one thing this refuses to do. Pass `onUnproven` when an expiry is news
|
|
432
455
|
you want.
|
|
433
456
|
|
|
434
|
-
`onSettled` is handed a `
|
|
457
|
+
`onSettled` is handed a `SelfConsistent<Settlement>`, so the preimage is a `string` rather
|
|
435
458
|
than something to coerce: the check the route already ran is what narrows it.
|
|
436
459
|
|
|
437
460
|
`gateway.serve.readSettlement` and `gateway.serve.readPayment` are the same checks
|
|
@@ -15,6 +15,120 @@ type Verified = {
|
|
|
15
15
|
/** Carries one request to an address ask() already verified, so nothing resolves the name again */
|
|
16
16
|
type Send = (url: string, sent: Sent, signal: AbortSignal, at: readonly Verified[]) => Promise<Response>;
|
|
17
17
|
|
|
18
|
+
/** A wallet reachable over NIP-47, as its `nostr+walletconnect://` URI describes it */
|
|
19
|
+
interface NwcConnection {
|
|
20
|
+
/** The wallet service's public key, which is what its answers have to be signed by */
|
|
21
|
+
walletPubkey: string;
|
|
22
|
+
/** Where to reach it, tried in order until one answers */
|
|
23
|
+
relays: string[];
|
|
24
|
+
/** Our own private key on this connection, and the only thing that authorises it */
|
|
25
|
+
secret: string;
|
|
26
|
+
}
|
|
27
|
+
/** A minted invoice and everything needed to watch it */
|
|
28
|
+
interface NwcInvoice {
|
|
29
|
+
bolt11: string;
|
|
30
|
+
paymentHash: string;
|
|
31
|
+
expiresAt: number;
|
|
32
|
+
}
|
|
33
|
+
/** The endpoint the gateway polls for an NWC payment, answering off your own wallet */
|
|
34
|
+
interface NwcVerifyConfig {
|
|
35
|
+
/** The wallet this endpoint speaks for. It never leaves this process */
|
|
36
|
+
connection: NwcConnection;
|
|
37
|
+
/** The secret the payment hash was sealed with, and nothing else uses it */
|
|
38
|
+
secret: string;
|
|
39
|
+
/** How often the gateway should ask, in seconds, sent as `Cache-Control: max-age`, `5` by default */
|
|
40
|
+
pollEverySecs?: number;
|
|
41
|
+
/** How long one `lookup_invoice` may take before the wallet counts as unreachable, `10_000` by default */
|
|
42
|
+
askTimeoutMs?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Read a `nostr+walletconnect://` URI. Refuses a relay that is not `wss`, for the
|
|
46
|
+
* reason the gateway refuses a verify URL that is not https
|
|
47
|
+
*/
|
|
48
|
+
declare function nwcConnection(uri: string): NwcConnection;
|
|
49
|
+
/** Mint an invoice on the connected wallet, decoded so the caller need not trust its word */
|
|
50
|
+
declare function nwcInvoice(connection: NwcConnection, amountMsat: number, description: string, timeoutMs?: number): Promise<NwcInvoice>;
|
|
51
|
+
/**
|
|
52
|
+
* Mint a hold invoice on a hash the wallet does not hold the preimage for, which
|
|
53
|
+
* is what lets an operator be paid only by paying somebody else first. The hash
|
|
54
|
+
* has to come from the recipient's own invoice, and the invoice that comes back
|
|
55
|
+
* is decoded rather than believed
|
|
56
|
+
*/
|
|
57
|
+
declare function nwcHoldInvoice(connection: NwcConnection, held: {
|
|
58
|
+
paymentHash: string;
|
|
59
|
+
amountMsat: number;
|
|
60
|
+
description: string;
|
|
61
|
+
expirySecs: number;
|
|
62
|
+
minCltvExpiryDelta?: number;
|
|
63
|
+
}, timeoutMs?: number): Promise<NwcInvoice>;
|
|
64
|
+
/**
|
|
65
|
+
* The preimage the wallet released for this hash, null while it has released
|
|
66
|
+
* none. A preimage that does not hash to what was asked for is a lie rather than
|
|
67
|
+
* an answer, so it throws instead of being passed on
|
|
68
|
+
*/
|
|
69
|
+
declare function nwcSettlement(connection: NwcConnection, paymentHash: string, timeoutMs?: number): Promise<string | null>;
|
|
70
|
+
/**
|
|
71
|
+
* Pay an invoice and keep the preimage the network handed back. Whoever pays
|
|
72
|
+
* learns it, which is what makes delivery provable to a recipient publishing no
|
|
73
|
+
* LUD-21 of their own. A preimage that does not hash to the invoice's own hash is
|
|
74
|
+
* a lie rather than a receipt, so it throws instead of being passed on
|
|
75
|
+
*/
|
|
76
|
+
declare function nwcPay(connection: NwcConnection, bolt11: string, timeoutMs?: number): Promise<string>;
|
|
77
|
+
/**
|
|
78
|
+
* A verify endpoint of your own that asks your wallet over NIP-47, so the gateway
|
|
79
|
+
* polls you and never learns the connection, the relay, or which wallet it is.
|
|
80
|
+
*
|
|
81
|
+
* `nwcVerifyUrl` seals the payment hash into the query with your secret, which is
|
|
82
|
+
* what stops a stranger driving your wallet through this handler. It answers the
|
|
83
|
+
* LUD-21 shape the gateway already speaks, so nothing on that side changes.
|
|
84
|
+
*
|
|
85
|
+
* A wallet it cannot reach answers `502` rather than "not settled", because those
|
|
86
|
+
* are different claims and only one of them is true.
|
|
87
|
+
*/
|
|
88
|
+
declare function nwcVerifyEndpoint(config: NwcVerifyConfig): (request: Request) => Promise<Response>;
|
|
89
|
+
/**
|
|
90
|
+
* The URL to hand the gateway, with the payment hash sealed inside it. Point it at
|
|
91
|
+
* wherever `nwcVerifyEndpoint` is mounted
|
|
92
|
+
*/
|
|
93
|
+
declare function nwcVerifyUrl(endpoint: string, paymentHash: string, secret: string): Promise<string>;
|
|
94
|
+
/**
|
|
95
|
+
* One NIP-47 call, for a method this SDK does not wrap. The wallet's own info
|
|
96
|
+
* event lists what it will answer, and anything it refuses comes back as a
|
|
97
|
+
* `WalletRefused` whose `reason` says which kind of refusal it was
|
|
98
|
+
*/
|
|
99
|
+
declare function askWallet(connection: NwcConnection, method: string, params: Record<string, unknown>, timeoutMs?: number): Promise<Record<string, unknown>>;
|
|
100
|
+
/** A Lightning rail minting on a wallet of your own over NIP-47, bound once per shop */
|
|
101
|
+
interface NwcRailConfig extends RailConfig {
|
|
102
|
+
/** The wallet that mints, which never leaves this process */
|
|
103
|
+
connection: NwcConnection;
|
|
104
|
+
/**
|
|
105
|
+
* What to charge for one order, the order's own price converted at `rate` by
|
|
106
|
+
* default. Give it a function and the price is whatever you say
|
|
107
|
+
*/
|
|
108
|
+
amount?: (order: Order) => Amount;
|
|
109
|
+
/** Where the default conversion gets its rate, the median of four venues by default */
|
|
110
|
+
rate?: Ticker;
|
|
111
|
+
/** Where `serve.nwcVerify` is mounted, and the secret the hash is sealed with */
|
|
112
|
+
verifyThrough: {
|
|
113
|
+
endpoint: string;
|
|
114
|
+
secret: string;
|
|
115
|
+
};
|
|
116
|
+
/** What the payer's wallet shows, the order's reference by default */
|
|
117
|
+
description?: (order: Order) => string;
|
|
118
|
+
/** Sealed before the gateway sees it, the way the blind Lightning rail does */
|
|
119
|
+
sealed?: {
|
|
120
|
+
secret: string;
|
|
121
|
+
data: (order: Order) => unknown;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Sell for Lightning against a wallet of your own over NIP-47, for a wallet that
|
|
126
|
+
* has no LUD-21 address to be watched at. Your node mints the invoice and releases
|
|
127
|
+
* the preimage, so the proof comes from one hop nearer than any hosted address can
|
|
128
|
+
* manage, and the gateway sees a hash and a URL of yours
|
|
129
|
+
*/
|
|
130
|
+
declare function nwcRail(gateway: ThunderBridge, config: NwcRailConfig): Rail;
|
|
131
|
+
|
|
18
132
|
/** What a shop knows about a sale before any rail exists */
|
|
19
133
|
interface Order {
|
|
20
134
|
/** The bank matches it on the statement, and Lightning keys idempotency on it */
|
|
@@ -139,6 +253,13 @@ declare class Rails {
|
|
|
139
253
|
blindLightning(config: BlindLightningRailConfig): Rail;
|
|
140
254
|
/** A bank transfer, proved the way a Lightning payment is */
|
|
141
255
|
bank(config: BankRailConfig): Rail;
|
|
256
|
+
/**
|
|
257
|
+
* Lightning against a wallet of your own over NIP-47, for a wallet that has no
|
|
258
|
+
* LUD-21 address to be watched at. Your node mints the invoice and releases the
|
|
259
|
+
* preimage, so the proof comes from one hop nearer than any hosted address can
|
|
260
|
+
* manage, and the gateway sees a hash and a URL of yours
|
|
261
|
+
*/
|
|
262
|
+
nwc(config: NwcRailConfig): Rail;
|
|
142
263
|
/**
|
|
143
264
|
* One bank transfer without building a rail first, for a shop that asks for
|
|
144
265
|
* them one at a time rather than beside another payment method
|
|
@@ -358,26 +479,39 @@ interface Provable {
|
|
|
358
479
|
bolt11?: string | null;
|
|
359
480
|
}
|
|
360
481
|
/**
|
|
361
|
-
* A report `
|
|
362
|
-
* status is settled. Nothing downstream of the check needs a null guard
|
|
482
|
+
* A report `agreesWithItself` has already accepted, so the preimage is there and
|
|
483
|
+
* the status is settled. Nothing downstream of the check needs a null guard
|
|
363
484
|
*/
|
|
364
|
-
type
|
|
485
|
+
type SelfConsistent<T extends Provable> = T & {
|
|
365
486
|
status: "paid";
|
|
366
487
|
preimage: string;
|
|
367
488
|
};
|
|
368
489
|
/**
|
|
369
|
-
*
|
|
490
|
+
* What `SelfConsistent` was called before 2.2.0
|
|
491
|
+
*
|
|
492
|
+
* @deprecated Use `SelfConsistent`, which says the report was checked against itself and nothing else
|
|
493
|
+
*/
|
|
494
|
+
type Proven<T extends Provable> = SelfConsistent<T>;
|
|
495
|
+
/**
|
|
496
|
+
* Whether a report agrees with itself: it says paid, and it carries a preimage
|
|
370
497
|
* that hashes to the payment hash it itself names. Where an invoice comes with it,
|
|
371
498
|
* the invoice's own hash has to agree too.
|
|
372
499
|
*
|
|
373
500
|
* A payment, a settlement delivered to a webhook and a frame off a trigger all
|
|
374
|
-
* answer this, because all three carry those fields
|
|
375
|
-
*
|
|
501
|
+
* answer this, because all three carry those fields.
|
|
502
|
+
*
|
|
503
|
+
* It asks nobody anything and holds the report against nothing you hold, so a
|
|
504
|
+
* gateway that invents a preimage and names its hash passes it. Checking against
|
|
505
|
+
* the hash you hold is what `payment` and `settled` do, and only
|
|
506
|
+
* `proveSettlement` asks the recipient
|
|
507
|
+
*/
|
|
508
|
+
declare function agreesWithItself<T extends Provable>(report: T): report is SelfConsistent<T>;
|
|
509
|
+
/**
|
|
510
|
+
* What `agreesWithItself` was called before 2.2.0
|
|
376
511
|
*
|
|
377
|
-
*
|
|
378
|
-
* arrival. Only `proveSettlement` asks the recipient
|
|
512
|
+
* @deprecated Use `agreesWithItself`, because it proves nothing beyond the report itself
|
|
379
513
|
*/
|
|
380
|
-
declare
|
|
514
|
+
declare const carriesProof: typeof agreesWithItself;
|
|
381
515
|
/**
|
|
382
516
|
* The most an operator may add over the recipient's own amount, in millisatoshi.
|
|
383
517
|
* The proportion is what routing and the liquidity behind it costs, and the base
|
|
@@ -402,9 +536,15 @@ declare function wrapFeeCeiling(amountMsat: number, allowance?: WrapAllowance):
|
|
|
402
536
|
*/
|
|
403
537
|
declare function proveWrapped(wrapped: string, recipient: string, allowance?: WrapAllowance): void;
|
|
404
538
|
|
|
405
|
-
/**
|
|
539
|
+
/**
|
|
540
|
+
* How far the gateway's clock may drift from yours before a webhook is refused,
|
|
541
|
+
* and the URL you registered when a proxy in front of you hands requests on under
|
|
542
|
+
* another one. A delivery is signed for the URL it was sent to, so one made for
|
|
543
|
+
* somebody else's endpoint is refused here
|
|
544
|
+
*/
|
|
406
545
|
type WebhookOptions = {
|
|
407
546
|
toleranceSecs?: number;
|
|
547
|
+
url?: string;
|
|
408
548
|
};
|
|
409
549
|
/**
|
|
410
550
|
* What checks a delivery: the hex the gateway publishes at `/webhook-key`. There
|
|
@@ -434,7 +574,7 @@ interface WebhookHandlers {
|
|
|
434
574
|
* A settlement that proves itself: it says paid and its preimage hashes to the
|
|
435
575
|
* payment hash it names. This is the only callback a shop needs
|
|
436
576
|
*/
|
|
437
|
-
onSettled?: (settlement:
|
|
577
|
+
onSettled?: (settlement: SelfConsistent<Settlement>) => void | Promise<void>;
|
|
438
578
|
/**
|
|
439
579
|
* A delivery that carries no proof, so an expiry. Left unset, the handler
|
|
440
580
|
* answers `202` and does nothing, because acting on an unproven claim is the
|
|
@@ -450,14 +590,21 @@ interface WebhookHandlers {
|
|
|
450
590
|
credential?: WebhookCredential;
|
|
451
591
|
/** How far the gateway's clock may drift from yours, five minutes by default */
|
|
452
592
|
toleranceSecs?: number;
|
|
593
|
+
/**
|
|
594
|
+
* The URL you registered, when a proxy in front of you hands the request on
|
|
595
|
+
* under another host or scheme. Left unset, the request's own URL is what the
|
|
596
|
+
* delivery has to have been signed for
|
|
597
|
+
*/
|
|
598
|
+
url?: string;
|
|
453
599
|
}
|
|
454
600
|
/**
|
|
455
601
|
* Everything one gateway lets you mount, in one place so a caller never has to
|
|
456
602
|
* know which handler needs the gateway and which does not. Most of these took it
|
|
457
603
|
* as a config field before, and reaching them through the gateway deleted it.
|
|
458
604
|
*
|
|
459
|
-
* `
|
|
460
|
-
* because a reader looking for a handler should find every handler
|
|
605
|
+
* `lightningVerify`, `bankVerify` and `nwcVerify` need nothing from the gateway and
|
|
606
|
+
* are here anyway, because a reader looking for a handler should find every handler
|
|
607
|
+
* in one list
|
|
461
608
|
*/
|
|
462
609
|
declare class Serve {
|
|
463
610
|
private readonly gateway;
|
|
@@ -478,13 +625,24 @@ declare class Serve {
|
|
|
478
625
|
* A verify endpoint of your own that asks the recipient's wallet for you, so
|
|
479
626
|
* the gateway polls you and never the wallet
|
|
480
627
|
*/
|
|
628
|
+
lightningVerify(config: LightningVerifyConfig): Handler;
|
|
629
|
+
/**
|
|
630
|
+
* What `lightningVerify` was called before 2.2.0
|
|
631
|
+
*
|
|
632
|
+
* @deprecated Use `lightningVerify`, beside `bankVerify` and `nwcVerify`
|
|
633
|
+
*/
|
|
481
634
|
verify(config: LightningVerifyConfig): Handler;
|
|
482
635
|
/** The verify endpoint a bank rail is polled at, answering off your own statement */
|
|
483
636
|
bankVerify(config: BankVerifyConfig): Handler;
|
|
637
|
+
/**
|
|
638
|
+
* The verify endpoint an NWC rail is polled at, asking your own wallet over
|
|
639
|
+
* NIP-47, so the gateway never learns the connection, the relay or the wallet
|
|
640
|
+
*/
|
|
641
|
+
nwcVerify(config: NwcVerifyConfig): Handler;
|
|
484
642
|
/**
|
|
485
643
|
* The whole webhook route: it answers the gateway's challenge, checks the
|
|
486
644
|
* signature against the key the gateway publishes, refuses a settlement that
|
|
487
|
-
* proves nothing, and calls you for the one that does.
|
|
645
|
+
* proves nothing, and calls you once for the one that does.
|
|
488
646
|
*
|
|
489
647
|
* `export const POST = gateway.serve.webhook({ onSettled: fulfil })` is the
|
|
490
648
|
* entire integration
|
|
@@ -706,6 +864,10 @@ declare class ThunderBridge {
|
|
|
706
864
|
* the recipient's own wallet minted it, so a payer who pays the loser afterwards
|
|
707
865
|
* really does pay twice and that shows up on `follow` as a second settlement to
|
|
708
866
|
* refund.
|
|
867
|
+
*
|
|
868
|
+
* A leg the gateway is caught lying about before any leg is paid ends the wait
|
|
869
|
+
* with its `GatewayCheatError`, even when another leg is paid after it, so a
|
|
870
|
+
* detected cheat is never traded for a later win.
|
|
709
871
|
*/
|
|
710
872
|
firstSettled(held: Held[], options?: WaitOptions): Promise<Payment | null>;
|
|
711
873
|
/**
|
|
@@ -769,9 +931,13 @@ interface Credit {
|
|
|
769
931
|
/**
|
|
770
932
|
* Recent credits on one account, oldest or newest first, it makes no difference.
|
|
771
933
|
* This is the whole plugin seam: a bank is a function of this shape, and
|
|
772
|
-
* `fioStatement` is one implementation of it
|
|
934
|
+
* `fioStatement` is one implementation of it. One that knows how often it can
|
|
935
|
+
* have anything new says so in `freshEverySecs`, and `bankVerify` then asks the
|
|
936
|
+
* gateway to poll exactly that often
|
|
773
937
|
*/
|
|
774
|
-
type Statement = (sinceUnix: number) => Promise<Credit[]
|
|
938
|
+
type Statement = ((sinceUnix: number) => Promise<Credit[]>) & {
|
|
939
|
+
readonly freshEverySecs?: number;
|
|
940
|
+
};
|
|
775
941
|
/** One transfer to ask for: what is owed, where it lands, and where its arrival is read back from */
|
|
776
942
|
interface BankTransferParams {
|
|
777
943
|
/**
|
|
@@ -856,7 +1022,9 @@ interface BankVerifyConfig {
|
|
|
856
1022
|
* How often you want the gateway to ask, in seconds. It goes out as
|
|
857
1023
|
* `Cache-Control: max-age`, so the pace is yours to set rather than the
|
|
858
1024
|
* gateway's, and a bank that updates once a minute should say so instead of
|
|
859
|
-
* being polled every few seconds.
|
|
1025
|
+
* being polled every few seconds. By default as often as the statement can have
|
|
1026
|
+
* anything new, which for `fioStatement` is thirty seconds divided by its tokens,
|
|
1027
|
+
* and thirty for a statement that does not say
|
|
860
1028
|
*/
|
|
861
1029
|
pollEverySecs?: number;
|
|
862
1030
|
}
|
|
@@ -893,4 +1061,4 @@ interface BankAgentConfig {
|
|
|
893
1061
|
*/
|
|
894
1062
|
declare function bankAgent(config: BankAgentConfig): () => void;
|
|
895
1063
|
|
|
896
|
-
export { type AttendOptions as A, type BankAgentConfig as B, type Credit as C, type
|
|
1064
|
+
export { type WebhookOptions as $, type AttendOptions as A, type BankAgentConfig as B, type Credit as C, type Proven as D, type RailConfig as E, type FollowOptions as F, Rails as G, type Handler as H, type Range as I, type Relayed as J, type SelfConsistent as K, type Leg as L, type Minted as M, type NwcConnection as N, type Order as O, type PaymentRequest as P, type Send as Q, type Rail as R, type Statement as S, ThunderBridge as T, Serve as U, type TicketOptions as V, type WaitOptions as W, type TriggerConfig as X, type WatchTicketConfig as Y, type WebhookCredential as Z, type WebhookHandlers as _, type BankOrder as a, type WrapAllowance as a0, agreesWithItself as a1, answerVerifyChallenge as a2, carriesProof as a3, invoiceFrom as a4, proveOrigin as a5, proveSettlement as a6, proveWrapped as a7, relayedVerifyUrl as a8, wrapFeeCeiling as a9, type BankTransfer as b, type BankTransferParams as c, type BankVerifyConfig as d, bankAgent as e, nwcVerifyEndpoint as f, type NwcInvoice as g, type NwcRailConfig as h, type NwcVerifyConfig as i, askWallet as j, nwcConnection as k, nwcHoldInvoice as l, nwcInvoice as m, nwcRail as n, nwcPay as o, nwcSettlement as p, nwcVerifyUrl as q, type ThunderBridgeOptions as r, type BankRailConfig as s, type BlindLightningRailConfig as t, type CreateOptions as u, type LightningRailConfig as v, type LightningVerifyConfig as w, type PaymentRequestInit as x, type PaymentRequestOptions as y, type Provable as z };
|