thunder-bridge 1.4.1 → 1.5.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.
@@ -0,0 +1,733 @@
1
+ import { R as Resolved, Q as QrOptions } from './qr-CF-YeXU1.js';
2
+ import { A as Amount, T as Ticker, C as Charge, e as MintedPayment, g as PaymentStatus, h as Priced, f as Msat, S as Settlement, P as Payment, Q as Quote, H as Handover, i as SocketTicket } from './types-BNPmVnA7.js';
3
+ import { a as BankTransferParams, B as BankTransfer, b as BankVerifyConfig } from './bank-B3mHISn1.js';
4
+
5
+ type Sent = {
6
+ method?: string;
7
+ headers?: Record<string, string>;
8
+ body?: string;
9
+ deadline?: AbortSignal;
10
+ };
11
+ type Verified = {
12
+ address: string;
13
+ family: number;
14
+ };
15
+ /** Carries one request to an address ask() already verified, so nothing resolves the name again */
16
+ type Send = (url: string, sent: Sent, signal: AbortSignal, at: readonly Verified[]) => Promise<Response>;
17
+
18
+ /** What a shop knows about a sale before any rail exists */
19
+ interface Order {
20
+ /** The bank matches it on the statement, and Lightning keys idempotency on it */
21
+ reference: string;
22
+ /** The price in the smallest unit of `currency`, so 48055 is 480.55 CZK */
23
+ amountMinor: number;
24
+ /** ISO 4217. The bank rail moves this, Lightning converts it at `rate` */
25
+ currency: string;
26
+ }
27
+ /** One way to pay one order, already registered with the gateway */
28
+ interface Leg {
29
+ /** The watched payment's id, which is what `firstSettled`, `payment` and `settled` take */
30
+ id: string;
31
+ /** Which rail made it, so a shop can label a leg without knowing how it was built */
32
+ rail: string;
33
+ /** What the payer reads, a BOLT11 invoice or a Short Payment Descriptor */
34
+ scan: string;
35
+ /** The same thing as a QR has to encode it, which is not always `scan` itself */
36
+ qr: string;
37
+ expiresAt: number;
38
+ }
39
+ /**
40
+ * A payment method. Everything that differs between rails is bound once when the
41
+ * rail is built, so the only thing passed per sale is which sale it is
42
+ */
43
+ type Rail = (order: Order) => Promise<Leg>;
44
+ /** What every rail takes, whatever it moves */
45
+ interface RailConfig {
46
+ /** Groups every payment from this rail so `follow` can watch the shop */
47
+ trigger?: string;
48
+ /** How many of that trigger's settlements the gateway keeps replayable past the hour */
49
+ replay?: number;
50
+ /** Where the gateway posts once the money lands, a public https URL */
51
+ webhookUrl?: string;
52
+ /** What `Leg.rail` says, so two rails of one kind can be told apart */
53
+ name?: string;
54
+ }
55
+ /** A Lightning rail the gateway mints for, bound once and then given one order at a time */
56
+ interface LightningRailConfig extends RailConfig {
57
+ /** Priority list, the first address that can prove an invoice wins */
58
+ paidTo: string | string[];
59
+ /**
60
+ * What to charge for one order, the order's own price converted at `rate` by
61
+ * default. Give it a function and the price is whatever you say
62
+ */
63
+ amount?: (order: Order) => Amount;
64
+ /** Where the default conversion gets its rate, the median of four venues by default */
65
+ rate?: Ticker;
66
+ /** Makes the mint safe to retry, the order's reference by default */
67
+ idempotencyKey?: (order: Order) => string | undefined;
68
+ }
69
+ /** The same rail with the invoice resolved here, so the gateway is told neither address nor amount */
70
+ interface BlindLightningRailConfig extends LightningRailConfig {
71
+ /**
72
+ * What the watcher needs and the gateway must not read, sealed with `seal`
73
+ * before it goes anywhere near the gateway
74
+ */
75
+ sealed?: (order: Order) => string | Promise<string>;
76
+ /**
77
+ * Where your own `serve.verify` endpoint is mounted, and its secret. Without
78
+ * it the gateway is handed the wallet's own URL, which a gateway enforcing its
79
+ * verify challenge will refuse to poll
80
+ */
81
+ relayThrough?: {
82
+ endpoint: string;
83
+ secret: string;
84
+ };
85
+ /** How the rail reaches wallets, pinned to the address it verified unless you say otherwise */
86
+ send?: Send;
87
+ }
88
+ /** A bank rail: the account the money lands in, and where its arrival is read back from */
89
+ interface BankRailConfig extends RailConfig {
90
+ /** Long lived and server side. Every preimage is derived from it, so losing it loses every proof */
91
+ secret: string;
92
+ /** The account the money goes to, as an IBAN */
93
+ iban: string;
94
+ /** Where `serve.bankVerify` is mounted, a public https URL with no query of its own */
95
+ verifyUrl: string;
96
+ /** When this leg stops being payable, in unix seconds */
97
+ expiresAt: (order: Order) => number;
98
+ /** Sealed before the gateway sees it, the way the blind Lightning rail does */
99
+ sealed?: (order: Order) => string | Promise<string>;
100
+ /** The Czech variable symbol, taken off the reference's digits by default */
101
+ variableSymbol?: (order: Order) => string | undefined;
102
+ /**
103
+ * Register on a gateway you do not own anyway. The verify URL names the amount
104
+ * and the reference, so its operator could read your order book off the watches
105
+ */
106
+ allowPublicGateway?: boolean;
107
+ }
108
+ /**
109
+ * A provable invoice from the first address on the list that will issue one, which
110
+ * is what a client mints for itself rather than asking a gateway to. Everything the
111
+ * gateway needs to watch it comes back with everything you need to prove it came
112
+ * from the address you asked for, so you can hand over the first and keep the second.
113
+ *
114
+ * Server side: it resolves hostnames and refuses a private one, which no browser can
115
+ * do. Throws `NoWalletAvailableError` when no address on the list would serve
116
+ */
117
+ declare function invoiceFrom(paidTo: string | string[], amount: Amount, send?: Send): Promise<Resolved>;
118
+ /**
119
+ * One call per sale, whatever the rail moves. Each of these was a free function
120
+ * taking the gateway as a config field, and reaching them through the gateway is
121
+ * what deleted that field
122
+ */
123
+ declare class Rails {
124
+ private readonly gateway;
125
+ constructor(gateway: ThunderBridge);
126
+ /** Lightning, with the gateway minting against a priority list of addresses */
127
+ lightning(config: LightningRailConfig): Rail;
128
+ /**
129
+ * Lightning, with the invoice resolved here so the gateway is told neither the
130
+ * address nor the amount
131
+ */
132
+ blindLightning(config: BlindLightningRailConfig): Rail;
133
+ /** A bank transfer, proved the way a Lightning payment is */
134
+ bank(config: BankRailConfig): Rail;
135
+ /**
136
+ * One bank transfer without building a rail first, for a shop that asks for
137
+ * them one at a time rather than beside another payment method
138
+ */
139
+ transfer(params: BankTransferParams): Promise<BankTransfer>;
140
+ }
141
+
142
+ /**
143
+ * What to ask for: who is paid, how much, and how the QR should look. Every
144
+ * field beyond `paidTo` and `amount` has a default, so the shortest request
145
+ * names two
146
+ */
147
+ interface PaymentRequestInit extends Charge, PaymentRequestOptions {
148
+ }
149
+ /** What `requestPayment` takes beyond the charge itself */
150
+ interface PaymentRequestOptions extends WaitOptions {
151
+ /** Makes the mint safe to retry, so a reloaded checkout replays one invoice */
152
+ idempotencyKey?: string;
153
+ /** Groups this request with every other one carrying the same secret, for `follow` */
154
+ trigger?: string;
155
+ /** How many of that trigger's settlements the gateway keeps replayable past the hour */
156
+ replay?: number;
157
+ /** Size and colour of `qr`, 256 pixels and black by default */
158
+ qr?: QrOptions;
159
+ }
160
+ /**
161
+ * One payment asked for: the invoice to show, the QR to draw it with, and one
162
+ * way to find out it was paid. Everything on it is already proved against the
163
+ * recipient's own server, so nothing here is the gateway's word
164
+ */
165
+ interface PaymentRequest {
166
+ /** What the gateway calls this payment, which is what `payment` and `settled` take */
167
+ readonly id: string;
168
+ readonly bolt11: string;
169
+ readonly paymentHash: string;
170
+ readonly lnAddress: string;
171
+ readonly amountMsat: number;
172
+ /** When the invoice stops being payable, in unix seconds */
173
+ readonly expiresAt: number;
174
+ /** The invoice as an SVG QR, ready to put in an element's `innerHTML` */
175
+ readonly qr: string;
176
+ /** The payment as the gateway first reported it, for anything the fields above leave out */
177
+ readonly payment: MintedPayment;
178
+ /**
179
+ * Resolves once the money has arrived, and rejects when the invoice expires
180
+ * unpaid or the wait is aborted. It follows a WebSocket and reconnects through
181
+ * a drop, so this is one await rather than a poll.
182
+ *
183
+ * `gateway.settled(id)` is the wider question and ends on an expiry too. This
184
+ * one is about the payment that was asked for, and one that expired was never paid
185
+ */
186
+ paid(options?: WaitOptions): Promise<MintedPayment>;
187
+ /**
188
+ * The same wait as a callback, for a page that has something else to do.
189
+ * Returns a function that stops waiting
190
+ */
191
+ onPaid(arrived: (payment: MintedPayment) => void, failed?: (reason: unknown) => void): () => void;
192
+ /**
193
+ * Ask the recipient's own server whether it settled, and get the preimage it
194
+ * released or null. This is the only answer that comes from somewhere other
195
+ * than the gateway, so it is the one to ask when a payment matters
196
+ */
197
+ prove(): Promise<string | null>;
198
+ }
199
+
200
+ /** The wallet's own LUD-21 URL and the hash its preimage has to match */
201
+ interface Relayed {
202
+ url: string;
203
+ hash: string;
204
+ }
205
+ /** The verify endpoint that asks the wallet for the gateway, and how often it may be asked */
206
+ interface LightningVerifyConfig {
207
+ /** The secret the sealed wallet URL was made with, and nothing else uses it */
208
+ secret: string;
209
+ /**
210
+ * How often you want the gateway to ask, in seconds. It goes out as
211
+ * `Cache-Control: max-age`, so the pace is yours rather than the operator's.
212
+ * Five by default, which is what a Lightning checkout wants
213
+ */
214
+ pollEverySecs?: number;
215
+ /** How the relay reaches the wallet, pinned to the address it verified unless you say otherwise */
216
+ send?: Send;
217
+ }
218
+ /**
219
+ * The URL to hand the gateway instead of the wallet's own, with the wallet's
220
+ * sealed inside it. Point it at wherever `lightningVerifyEndpoint` is mounted
221
+ */
222
+ declare function relayedVerifyUrl(endpoint: string, wallet: Relayed, secret: string): Promise<string>;
223
+
224
+ /** An LNURL-pay endpoint of your own: whose wallets it stands for, and what it charges */
225
+ interface TriggerConfig {
226
+ /** Priority list, quoted at payRequest and then pinned for the callback */
227
+ paidTo: string | string[];
228
+ /**
229
+ * What this trigger costs right now, asked once per payRequest. `fiat` makes it
230
+ * a live rate, and any function of your own makes it a time of day rule.
231
+ *
232
+ * Give it a `{ least, most }` range instead and the payer chooses inside it,
233
+ * which is what a tip jar is. One amount pins the price and the wallet offers
234
+ * no field to type in
235
+ */
236
+ amount: Amount | Range;
237
+ /**
238
+ * Signs the callback URL. Without it anyone could call the callback and make
239
+ * this endpoint mint invoices on wallets of their choosing
240
+ */
241
+ secret: string;
242
+ /** Groups every payment here so `follow` can watch the place, keep it off the QR */
243
+ watchSecret?: string;
244
+ /**
245
+ * How many settlements of this place the gateway keeps replayable past the hour
246
+ * it would otherwise forget them in, up to the ceiling its operator set. What a
247
+ * page that opens later still gets to see. Needs `watchSecret`
248
+ */
249
+ replay?: number;
250
+ /** How the endpoint reaches wallets, pinned to the address it verified unless you say otherwise */
251
+ send?: Send;
252
+ /** Override when a proxy hides the public URL from the request, no trailing slash */
253
+ baseUrl?: string;
254
+ /**
255
+ * Resolve the address here and hand the gateway only a hash and a URL to poll,
256
+ * instead of asking it to mint. It then cannot tell who is being paid beyond
257
+ * the domain in the verify URL, nor how much at all, so the only refusal left
258
+ * to it is refusing everyone. Costs one more round trip and gives up the
259
+ * gateway's CORS proxying, which a server does not need anyway.
260
+ *
261
+ * A gateway that enforces its verify challenge will not poll a wallet's own
262
+ * LUD-21 URL, so pass `relayThrough` as well and the poll comes to you
263
+ */
264
+ blind?: boolean;
265
+ /**
266
+ * Where your own `serve.verify` endpoint is mounted, and the secret it was
267
+ * given. The wallet's URL is sealed inside the one the gateway is handed, so
268
+ * the gateway polls you and learns neither the wallet nor its provider
269
+ */
270
+ relayThrough?: {
271
+ endpoint: string;
272
+ secret: string;
273
+ };
274
+ /**
275
+ * What the watcher needs and the gateway must not have. `data` returns it and
276
+ * `secret` encrypts it, so there is no way to hand the gateway something it
277
+ * can read. Needs 32 characters of randomness, not a passphrase, and every
278
+ * watcher of this trigger holds the same one
279
+ */
280
+ sealed?: {
281
+ secret: string;
282
+ data: (minted: Minted) => unknown;
283
+ };
284
+ }
285
+ /** What a blind mint produced, which is what the sealed payload is built from */
286
+ /**
287
+ * What a payer may choose to send, when the endpoint lets them choose at all.
288
+ * Both ends are asked once per payRequest, so a fiat range moves with the rate
289
+ */
290
+ interface Range {
291
+ least: Amount;
292
+ most: Amount;
293
+ }
294
+ /** What a blind mint produced, which is what the sealed payload is built from */
295
+ interface Minted {
296
+ lnAddress: string;
297
+ amountMsat: number;
298
+ bolt11: string;
299
+ paymentHash: string;
300
+ verifyUrl: string;
301
+ expiresAt: number;
302
+ }
303
+ /**
304
+ * A trigger's live stream is opened with a ticket rather than with the watch
305
+ * secret, so something has to hold the secret and trade it for tickets. That is
306
+ * what these two endpoints are, and they are the only place the gateway's token
307
+ * has to be
308
+ */
309
+ interface WatchTicketConfig {
310
+ /** The trigger to open, the same secret `serve.lnurlPay` groups its payments under */
311
+ watchSecret: string;
312
+ /**
313
+ * How many of this trigger's settlements the socket replays on connect, so a
314
+ * page opened late still shows what it missed, up to the gateway's ceiling
315
+ */
316
+ replay?: number;
317
+ }
318
+
319
+ /**
320
+ * What a wrapping operator may charge over the recipient's own amount. This is a
321
+ * ceiling the client sets rather than a price the operator names, so it sits
322
+ * above what any operator lists and refuses only the ones reaching past it
323
+ */
324
+ interface WrapAllowance {
325
+ /** As a fraction of the recipient's amount, `0.01` by default */
326
+ proportion?: number;
327
+ /** The floor in millisatoshi whatever the fraction works out to, `1000` by default */
328
+ baseMsat?: number;
329
+ }
330
+ /**
331
+ * Prove the invoice really is the one the recipient issued for what you asked,
332
+ * before the payer ever sees it, both fetches go straight to the recipient's own
333
+ * server and none of them goes back to the gateway
334
+ *
335
+ * Throws `GatewayCheatError` when a check fails and `UnverifiedRecipientError`
336
+ * when the recipient could not be reached to run one
337
+ */
338
+ declare function proveOrigin(payment: MintedPayment, asked: Priced): Promise<void>;
339
+ /**
340
+ * Prove the money arrived by asking the recipient's own server, not the gateway,
341
+ * returns the preimage when the recipient says it settled and null when it says
342
+ * it has not, and runs the full origin proof first because a verify url the
343
+ * gateway made up would otherwise answer for itself
344
+ */
345
+ declare function proveSettlement(payment: MintedPayment, asked: Priced): Promise<string | null>;
346
+ /** The least a report has to carry for its own proof to be checkable */
347
+ interface Provable {
348
+ status: PaymentStatus;
349
+ preimage: string | null;
350
+ paymentHash: string;
351
+ bolt11?: string | null;
352
+ }
353
+ /**
354
+ * A report `carriesProof` has already accepted, so the preimage is there and the
355
+ * status is settled. Nothing downstream of the check needs a null guard
356
+ */
357
+ type Proven<T extends Provable> = T & {
358
+ status: "paid";
359
+ preimage: string;
360
+ };
361
+ /**
362
+ * Whether a report proves what it claims: it says paid, and it carries a preimage
363
+ * that hashes to the payment hash it itself names. Where an invoice comes with it,
364
+ * the invoice's own hash has to agree too.
365
+ *
366
+ * A payment, a settlement delivered to a webhook and a frame off a trigger all
367
+ * answer this, because all three carry those fields and no other question about
368
+ * one matters.
369
+ *
370
+ * It asks nobody anything, so it costs no round trip and is not a proof of
371
+ * arrival. Only `proveSettlement` asks the recipient
372
+ */
373
+ declare function carriesProof<T extends Provable>(report: T): report is Proven<T>;
374
+ /**
375
+ * The most an operator may add over the recipient's own amount, in millisatoshi.
376
+ * The proportion is what routing and the liquidity behind it costs, and the base
377
+ * is the floor it never drops below, because a fraction of a small payment
378
+ * rounds to nothing the operator can work for
379
+ */
380
+ declare function wrapFeeCeiling(amountMsat: number, allowance?: WrapAllowance): Msat;
381
+ /**
382
+ * Prove a wrapping operator's invoice is the recipient's own payment in
383
+ * disguise, so paying it can only settle by the operator paying the recipient.
384
+ *
385
+ * It compares two invoices and asks nobody anything, so it runs in a browser and
386
+ * costs no round trip. Prove the recipient's own invoice with `proveOrigin`
387
+ * first, because this says nothing about where that one came from.
388
+ *
389
+ * There is no settlement check here and there does not need to be. Both invoices
390
+ * carry one payment hash, so the preimage that settles the wrap is the preimage
391
+ * the recipient released, and `proveSettlement` already reads it from the
392
+ * recipient's own server.
393
+ *
394
+ * Throws `WrapRefusedError` naming which binding failed
395
+ */
396
+ declare function proveWrapped(wrapped: string, recipient: string, allowance?: WrapAllowance): void;
397
+
398
+ /** How far the gateway's clock may drift from yours before a webhook is refused */
399
+ type WebhookOptions = {
400
+ toleranceSecs?: number;
401
+ };
402
+ /**
403
+ * What checks a delivery: the hex the gateway publishes at `/webhook-key`. There
404
+ * is no shared secret to register, so a gateway holds nothing of yours. Rotating
405
+ * its cluster key rotates this too, so a signature that stops verifying is a
406
+ * reason to read the key again before it is a reason to distrust the gateway
407
+ */
408
+ type WebhookCredential = {
409
+ publicKey: string;
410
+ };
411
+ /**
412
+ * Answer the challenge the gateway sends a verify URL before it will poll it,
413
+ * which is how a caller shows the endpoint agreed to the traffic rather than
414
+ * merely being named. Returns null for anything that is not a challenge, so a
415
+ * verify endpoint hands the request on to its own reading of a payment.
416
+ *
417
+ * The nonce is echoed to whoever asked, which grants them nothing, so there is
418
+ * no signature to check here and no secret to hold
419
+ */
420
+ declare function answerVerifyChallenge(request: Request): Promise<Response | null>;
421
+
422
+ /** A Fetch handler, which is what every runtime this targets mounts */
423
+ type Handler = (request: Request) => Promise<Response>;
424
+ /** What to do with what the gateway delivers, and what to believe it with */
425
+ interface WebhookHandlers {
426
+ /**
427
+ * A settlement that proves itself: it says paid and its preimage hashes to the
428
+ * payment hash it names. This is the only callback a shop needs
429
+ */
430
+ onSettled?: (settlement: Proven<Settlement>) => void | Promise<void>;
431
+ /**
432
+ * A delivery that carries no proof, so an expiry or a paid claim with no
433
+ * preimage behind it. Left unset, the handler answers `202` and does nothing,
434
+ * because acting on an unproven claim is the one thing this refuses to do
435
+ */
436
+ onUnproven?: (settlement: Settlement) => void | Promise<void>;
437
+ /** A whole payment rather than a settlement, which is what an older gateway posts */
438
+ onPayment?: (payment: Payment) => void | Promise<void>;
439
+ /**
440
+ * The key that checks the signature, fetched from the gateway once and kept
441
+ * when you do not pass one. Pass it to pin the key you already read
442
+ */
443
+ credential?: WebhookCredential;
444
+ /** How far the gateway's clock may drift from yours, five minutes by default */
445
+ toleranceSecs?: number;
446
+ }
447
+ /**
448
+ * Everything one gateway lets you mount, in one place so a caller never has to
449
+ * know which handler needs the gateway and which does not. Most of these took it
450
+ * as a config field before, and reaching them through the gateway deleted it.
451
+ *
452
+ * `verify` and `bankVerify` need nothing from the gateway and are here anyway,
453
+ * because a reader looking for a handler should find every handler in one list
454
+ */
455
+ declare class Serve {
456
+ private readonly gateway;
457
+ constructor(gateway: ThunderBridge);
458
+ /**
459
+ * An LNURL-pay endpoint of your own, standing in front of a priority list of
460
+ * addresses, so a printed QR points at your domain and never expires
461
+ */
462
+ lnurlPay(config: TriggerConfig): Handler;
463
+ /** Trades the watch secret for a one minute socket ticket, refusing anyone without it */
464
+ watchTicket(config: WatchTicketConfig): Handler;
465
+ /**
466
+ * Mints a socket ticket for anybody who asks, which makes the trigger's whole
467
+ * stream public, preimages included. Only for a board where that is the point
468
+ */
469
+ publicWatchTicket(config: WatchTicketConfig): Handler;
470
+ /**
471
+ * A verify endpoint of your own that asks the recipient's wallet for you, so
472
+ * the gateway polls you and never the wallet
473
+ */
474
+ verify(config: LightningVerifyConfig): Handler;
475
+ /** The verify endpoint a bank rail is polled at, answering off your own statement */
476
+ bankVerify(config: BankVerifyConfig): Handler;
477
+ /**
478
+ * The whole webhook route: it answers the gateway's challenge, checks the
479
+ * signature against the key the gateway publishes, refuses a settlement that
480
+ * proves nothing, and calls you for the one that does.
481
+ *
482
+ * `export const POST = gateway.serve.webhook({ onSettled: fulfil })` is the
483
+ * entire integration
484
+ */
485
+ webhook(handlers: WebhookHandlers): Handler;
486
+ /** Verify a delivery and read the settlement out of it, null when it is not believable */
487
+ readSettlement(request: Request, options?: WebhookOptions): Promise<Settlement | null>;
488
+ /** Verify a delivery and read the payment out of it, null when it is not believable */
489
+ readPayment(request: Request, options?: WebhookOptions): Promise<Payment | null>;
490
+ /** Answer the challenge the gateway sends before it will post to a webhook of yours */
491
+ answerWebhookChallenge(request: Request, options?: WebhookOptions): Promise<Response | null>;
492
+ private credential;
493
+ }
494
+
495
+ /** How this instance talks to one gateway, and how much of what it says to check */
496
+ interface ThunderBridgeOptions {
497
+ /**
498
+ * Prove every payment against the recipient's own server before handing it
499
+ * back, and refuse a reported settlement whose preimage does not hash to the
500
+ * payment hash, defaults to true
501
+ */
502
+ verify?: boolean;
503
+ /**
504
+ * Sent as `Authorization: Bearer`, which a gateway started with
505
+ * `GATEWAY_TOKEN` requires on every call, the socket handshake included. No
506
+ * browser WebSocket can carry a header, so setting this also puts every socket
507
+ * through a ticket
508
+ */
509
+ token?: string;
510
+ /**
511
+ * The same long lived server side secret your rail derives its preimages from.
512
+ * Given here, every call carries a signature the gateway reads as your identity,
513
+ * so a payment you create is handed back to you and to nobody else. Withheld,
514
+ * you are anonymous and any holder of an id can read what it names
515
+ */
516
+ secret?: string;
517
+ }
518
+ /** How long to wait on a payment, and what the socket URL is allowed to carry */
519
+ interface WaitOptions {
520
+ /** Give up when this aborts, `AbortSignal.timeout(ms)` covers the usual case */
521
+ signal?: AbortSignal;
522
+ /**
523
+ * Mint a short-lived ticket and put that in the socket URL instead of the
524
+ * payment id. Implied by `token`. The id stays readable inside the ticket,
525
+ * what changes is that a URL out of a log stops opening anything after a
526
+ * minute
527
+ */
528
+ tickets?: boolean;
529
+ }
530
+ /** What a socket ticket opens beyond the trigger it names */
531
+ interface TicketOptions {
532
+ /**
533
+ * How many of this trigger's settlements the socket replays on connect, up to
534
+ * the ceiling the gateway's operator set
535
+ */
536
+ replay?: number;
537
+ }
538
+ /** What a mint carries beyond the charge: a retry key, and which trigger it joins */
539
+ interface CreateOptions {
540
+ /**
541
+ * Makes the POST safe to retry. A repeat of a finished request replays its
542
+ * payment instead of asking a wallet for a second invoice, a repeat that
543
+ * arrives while the first is still resolving throws
544
+ * `IdempotencyConflictError`, and the key is held for 24 hours
545
+ */
546
+ idempotencyKey?: string;
547
+ /**
548
+ * Groups this payment with every other one carrying the same secret, so
549
+ * `follow` can watch the place rather than the payment. Registering
550
+ * sends only its sha256, which is also all the gateway stores, so a stolen
551
+ * ledger cannot subscribe. Following sends the secret itself, because the
552
+ * gateway hashes what it is given to find the stream, so the operator of a
553
+ * gateway you do not own learns it the first time you connect. Keep it apart
554
+ * from any URL a payer sees
555
+ */
556
+ trigger?: string;
557
+ /**
558
+ * How many of the trigger's settlements the gateway keeps replayable past the
559
+ * hour it would otherwise forget them in, up to the ceiling its operator set.
560
+ * Needs `trigger`, defaults to none
561
+ */
562
+ replay?: number;
563
+ }
564
+ /** What to do with a trigger's settlements, and how hard to try to keep hearing them */
565
+ interface FollowOptions {
566
+ /** Called for the recent settlements replayed on connect, then for each new one */
567
+ onPayment: (settled: Payment) => void;
568
+ /**
569
+ * How many settlements to ask for on connect, defaults to the gateway's ten.
570
+ * It hands back what it still holds, which is the last hour unless the
571
+ * payments were minted with `replay`
572
+ */
573
+ replay?: number;
574
+ /** Called when a connection drops or a frame is refused, the follow keeps going */
575
+ onError?: (error: unknown) => void;
576
+ /** Reconnect after a drop, defaults to true */
577
+ reconnect?: boolean;
578
+ /**
579
+ * The first wait after a drop, doubling up to 30 seconds and jittered so a
580
+ * fleet does not come back in lockstep, defaults to 3000. A connection that
581
+ * opens puts it back to the first wait
582
+ */
583
+ reconnectDelayMs?: number;
584
+ /**
585
+ * Mint a short-lived ticket and put that in the socket URL instead of the
586
+ * secret, one per connection. Keeps the secret out of access logs, at the cost
587
+ * of a POST before each connect. Implied by `token`. Leave it off for a
588
+ * microcontroller, where one hardcoded URL and a dumb reconnect loop is the
589
+ * whole point
590
+ */
591
+ tickets?: boolean;
592
+ }
593
+ /** Talks to a Thunder Bridge gateway and trusts it for nothing it can check itself */
594
+ declare class ThunderBridge {
595
+ private readonly baseUrl;
596
+ private readonly verify;
597
+ private readonly token;
598
+ private readonly secret;
599
+ private strangers;
600
+ private speaks;
601
+ private published;
602
+ /** Everything this gateway lets you mount, from an LNURL endpoint to a webhook route */
603
+ readonly serve: Serve;
604
+ /** One call per sale, whatever the rail moves */
605
+ readonly rails: Rails;
606
+ constructor(baseUrl: string, options?: ThunderBridgeOptions);
607
+ /**
608
+ * Whether a token was given to this instance, which is your side of the
609
+ * arrangement and says nothing about the gateway's. `refusesStrangers` is the
610
+ * one that asks the gateway, and it is the one to guard anything with
611
+ */
612
+ get hasToken(): boolean;
613
+ /**
614
+ * Whether the gateway turns away a caller carrying no token, asked by making
615
+ * one unauthenticated read it would have to refuse. `hasToken` answers only
616
+ * whether you configured one, so a made-up token against a public instance
617
+ * reads as yours and is not. Asked once and remembered, because an instance
618
+ * does not change its mind. Anything other than a refusal counts as open, so
619
+ * an unreachable gateway fails closed
620
+ */
621
+ refusesStrangers(): Promise<boolean>;
622
+ /**
623
+ * Ask to be paid for one thing. It mints the invoice, proves it came from the
624
+ * address you asked for, draws the QR and hands back one object with a way to
625
+ * wait for the money. This is `mint` plus the two things every caller does next
626
+ */
627
+ requestPayment(asked: PaymentRequestInit): Promise<PaymentRequest>;
628
+ /**
629
+ * Ask the gateway for an invoice payable to the first address on your list
630
+ * that can issue a provable one, throws `NoWalletAvailableError` when none can
631
+ * and `GatewayCheatError` when what comes back is not what you asked for
632
+ */
633
+ mint(charge: Charge, options?: CreateOptions): Promise<MintedPayment>;
634
+ /**
635
+ * Ask which address would serve an amount without minting anything, throws
636
+ * `NoWalletAvailableError` when none would. A quote is a probe and not a
637
+ * promise: the address it names can still be refused at create time, because
638
+ * whether a wallet returns a provable invoice cannot be known without asking
639
+ * it for one, and asking mints it
640
+ */
641
+ quote(charge: Charge): Promise<Quote>;
642
+ /**
643
+ * The key this gateway signs webhooks with when you registered none of your own.
644
+ * `serve.webhook` reads it for you. Asked once and kept, because it is the same
645
+ * for every instance in the cluster
646
+ */
647
+ webhookKey(): Promise<string>;
648
+ private publishedKey;
649
+ /**
650
+ * Read a payment back, null when the gateway has never heard of it. One method
651
+ * for both sorts: `kind` says whether the gateway minted it or was handed it,
652
+ * and the address, amount and invoice are null on one it was never told
653
+ */
654
+ payment(id: string): Promise<Payment | null>;
655
+ /**
656
+ * List what this gateway is watching, newest first. Only a gateway started
657
+ * with `GATEWAY_TOKEN` serves this, because on a shared one it would hand
658
+ * every caller everyone else's payments, so a public gateway answers 404.
659
+ *
660
+ * `scanned` says how many settled records were looked at to build the page.
661
+ * Anything older than that window is not in the answer, and the list does not
662
+ * pretend otherwise
663
+ */
664
+ payments(limit?: number): Promise<{
665
+ payments: Payment[];
666
+ scanned: number;
667
+ }>;
668
+ /**
669
+ * Follow a payment over WebSocket until it is paid or expired, reconnecting
670
+ * through a drop. A payment that never answers gives up after a few tries, and
671
+ * one that has answered is followed until its own expiry, so the wait always
672
+ * ends by itself
673
+ */
674
+ settled(id: string, options?: WaitOptions): Promise<Payment>;
675
+ private followed;
676
+ /**
677
+ * Wait on several payments and keep the first one that is really paid, then stop
678
+ * waiting on the losers, which closes their sockets.
679
+ *
680
+ * This is how one order offers two rails. A Lightning invoice and a bank
681
+ * transfer for the same thing are two payments here, and the payer picks one, so
682
+ * what you want is the one that arrives and nothing further from the other.
683
+ *
684
+ * A leg that expires is a loser, not a winner, which is the whole reason this is
685
+ * not a race: `settled` ends on `paid` and on `expired` alike, and a
686
+ * Lightning invoice expires in an hour while a bank transfer takes days. `null`
687
+ * means every leg ended without being paid.
688
+ *
689
+ * Stopping the wait is not revoking the invoice. Nobody can revoke one, because
690
+ * the recipient's own wallet minted it, so a payer who pays the loser afterwards
691
+ * really does pay twice and that shows up on `follow` as a second settlement to
692
+ * refund.
693
+ */
694
+ firstSettled(ids: string[], options?: WaitOptions): Promise<Payment | null>;
695
+ /**
696
+ * Hand over an invoice you obtained yourself so the gateway watches it without
697
+ * being told the address or the amount. It can then only refuse everyone
698
+ * rather than one recipient, which is what makes leaving it cheap. Anything
699
+ * the watcher needs goes in `sealed`, which the gateway cannot read
700
+ */
701
+ watch(handover: Handover): Promise<Payment>;
702
+ /**
703
+ * What this payment is called, which you can work out before any gateway has
704
+ * heard of it. Every gateway you hand the same invoice to answers with the same
705
+ * name, so watching at several of them adds up to one payment rather than
706
+ * several, and no gateway's key is in the answer. Null when no secret was given,
707
+ * because then the gateway names the payment and only it can
708
+ */
709
+ nameFor(paymentHash: string): Promise<string | null>;
710
+ /**
711
+ * Follow every payment made to one trigger, replayed from the recent ones on
712
+ * connect and then live, reconnecting on its own until the returned function
713
+ * is called. A trigger has no terminal state, so this never resolves
714
+ */
715
+ follow(secret: string, options: FollowOptions): () => void;
716
+ /**
717
+ * A one minute pass onto one trigger's stream, for something that must hold
718
+ * neither the token nor the trigger secret. Mint it in a handler and answer
719
+ * with the ticket alone, because that is all a browser needs to connect and
720
+ * all it can do anything with. `serve.watchTicket` is this method already
721
+ * wrapped in a route
722
+ */
723
+ ticket(trigger: string, options?: TicketOptions): Promise<SocketTicket>;
724
+ private needsTicket;
725
+ private wsTicket;
726
+ private mintedTicket;
727
+ private sending;
728
+ private reading;
729
+ private speaking;
730
+ private proven;
731
+ }
732
+
733
+ export { relayedVerifyUrl as A, type BankRailConfig as B, type CreateOptions as C, wrapFeeCeiling as D, type FollowOptions as F, type Handler as H, type Leg as L, type Minted as M, type Order as O, type PaymentRequest as P, type RailConfig as R, type Send as S, ThunderBridge as T, type WaitOptions as W, type Rail as a, type ThunderBridgeOptions as b, type BlindLightningRailConfig as c, type LightningRailConfig as d, type LightningVerifyConfig as e, type PaymentRequestInit as f, type PaymentRequestOptions as g, type Provable as h, type Proven as i, Rails as j, type Range as k, type Relayed as l, Serve as m, type TicketOptions as n, type TriggerConfig as o, type WatchTicketConfig as p, type WebhookCredential as q, type WebhookHandlers as r, type WebhookOptions as s, type WrapAllowance as t, answerVerifyChallenge as u, carriesProof as v, invoiceFrom as w, proveOrigin as x, proveSettlement as y, proveWrapped as z };