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 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, `nwcRail` from `thunder-bridge/nwc` is the way round it: your own
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.verify` endpoint, once `relayThrough` is set. Leave it off and the gateway polls the wallet directly, as on the minted rail |
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
- | `nwcRail` | your own wallet mints it, over NIP-47 `make_invoice` |
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 `nwcVerifyEndpoint` |
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, which names the amount and the reference |
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 | you, `pollEverySecs` |
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
- **`nwcRail`**
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
- `carriesProof` is the one to be careful with: it asks only whether a report holds
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 for Lightning and for a bank, the webhook route,
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`, `carriesProof`, `decodeInvoice`, `preimageMatchesHash`
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 is signed `ed25519=<signature>` with the key the gateway
404
- publishes at `/webhook-key`, over `<x-timestamp>.<raw body>` rather than the body
405
- alone, so a captured delivery cannot be replayed at you later. Delivery is
406
- at-least-once, so deduplicate on `id`.
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 `Proven<Settlement>`, so the preimage is a `string` rather
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 `carriesProof` has already accepted, so the preimage is there and the
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 Proven<T extends Provable> = T & {
485
+ type SelfConsistent<T extends Provable> = T & {
365
486
  status: "paid";
366
487
  preimage: string;
367
488
  };
368
489
  /**
369
- * Whether a report proves what it claims: it says paid, and it carries a preimage
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 and no other question about
375
- * one matters.
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
- * It asks nobody anything, so it costs no round trip and is not a proof of
378
- * arrival. Only `proveSettlement` asks the recipient
512
+ * @deprecated Use `agreesWithItself`, because it proves nothing beyond the report itself
379
513
  */
380
- declare function carriesProof<T extends Provable>(report: T): report is Proven<T>;
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
- /** How far the gateway's clock may drift from yours before a webhook is refused */
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: Proven<Settlement>) => void | Promise<void>;
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
- * `verify` and `bankVerify` need nothing from the gateway and are here anyway,
460
- * because a reader looking for a handler should find every handler in one list
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. Thirty by default, clamped to an hour
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 WebhookOptions as D, type WrapAllowance as E, type FollowOptions as F, answerVerifyChallenge as G, type Handler as H, carriesProof as I, invoiceFrom as J, proveOrigin as K, type Leg as L, type Minted as M, proveSettlement as N, type Order as O, type PaymentRequest as P, proveWrapped as Q, type RailConfig as R, type Statement as S, ThunderBridge as T, relayedVerifyUrl as U, wrapFeeCeiling as V, type WaitOptions as W, type BankOrder as a, type BankTransfer as b, type BankTransferParams as c, type BankVerifyConfig as d, bankAgent as e, type Rail as f, type ThunderBridgeOptions as g, type BankRailConfig as h, type BlindLightningRailConfig as i, type CreateOptions as j, type LightningRailConfig as k, type LightningVerifyConfig as l, type PaymentRequestInit as m, type PaymentRequestOptions as n, type Provable as o, type Proven as p, Rails as q, type Range as r, type Relayed as s, type Send as t, Serve as u, type TicketOptions as v, type TriggerConfig as w, type WatchTicketConfig as x, type WebhookCredential as y, type WebhookHandlers as z };
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 };