thunder-bridge 0.8.10 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,7 +23,6 @@ interface CreatePaymentParams {
23
23
  lnAddresses: string[];
24
24
  amountMsat: number;
25
25
  webhookUrl?: string;
26
- webhookSecret?: string;
27
26
  }
28
27
  /**
29
28
  * `lnAddresses` is the same priority list `createPayment` takes, and quoting it
@@ -78,7 +77,6 @@ interface WatchPaymentParams {
78
77
  trigger?: string;
79
78
  sealed?: string;
80
79
  webhookUrl?: string;
81
- webhookSecret?: string;
82
80
  }
83
81
  /** Why one wallet in the list could not be used */
84
82
  type WalletReason = "address-unusable" | "unreachable" | "amount-not-accepted" | "cannot-prove-delivery" | "invoice-refused";
@@ -86,6 +84,17 @@ interface WalletFailure {
86
84
  address: string;
87
85
  reason: WalletReason;
88
86
  }
87
+ /**
88
+ * What a delivery carries. Everything needed to act on a settlement and to check
89
+ * it, and nothing else, so a retry is the same size every time
90
+ */
91
+ interface Settlement {
92
+ id: string;
93
+ status: PaymentStatus;
94
+ paymentHash: string;
95
+ preimage: string | null;
96
+ settledAt: number;
97
+ }
89
98
 
90
99
  interface ThunderBridgeOptions {
91
100
  /**
@@ -101,6 +110,13 @@ interface ThunderBridgeOptions {
101
110
  * through a ticket
102
111
  */
103
112
  token?: string;
113
+ /**
114
+ * The same long lived server side secret your rail derives its preimages from.
115
+ * Given here, every call carries a signature the gateway reads as your identity,
116
+ * so a payment you create is handed back to you and to nobody else. Withheld,
117
+ * you are anonymous and any holder of an id can read what it names
118
+ */
119
+ secret?: string;
104
120
  }
105
121
  interface WaitOptions {
106
122
  /** Give up when this aborts, `AbortSignal.timeout(ms)` covers the usual case */
@@ -159,7 +175,9 @@ declare class ThunderBridge {
159
175
  private readonly baseUrl;
160
176
  private readonly verify;
161
177
  private readonly token;
178
+ private readonly secret;
162
179
  private strangers;
180
+ private speaks;
163
181
  constructor(baseUrl: string, options?: ThunderBridgeOptions);
164
182
  /**
165
183
  * Whether a token was given, which is what makes an instance yours: a gateway
@@ -262,6 +280,14 @@ declare class ThunderBridge {
262
280
  * the watcher needs goes in `sealed`, which the gateway cannot read
263
281
  */
264
282
  watchPayment(params: WatchPaymentParams): Promise<TriggerEvent>;
283
+ /**
284
+ * What this payment is called, which you can work out before any gateway has
285
+ * heard of it. Every gateway you hand the same invoice to answers with the same
286
+ * name, so watching at several of them adds up to one payment rather than
287
+ * several, and no gateway's key is in the answer. Null when no secret was given,
288
+ * because then the gateway names the payment and only it can
289
+ */
290
+ nameFor(paymentHash: string): Promise<string | null>;
265
291
  /**
266
292
  * Follow every payment made to one trigger, replayed from the recent ones on
267
293
  * connect and then live, reconnecting on its own until the returned function
@@ -272,6 +298,7 @@ declare class ThunderBridge {
272
298
  private wsTicket;
273
299
  private sending;
274
300
  private reading;
301
+ private speaking;
275
302
  private proven;
276
303
  private checked;
277
304
  }
@@ -324,7 +351,6 @@ interface BankRailConfig {
324
351
  /** Up to ten digits, for accounting systems that still want one */
325
352
  variableSymbol?: (order: Order) => string | undefined;
326
353
  webhookUrl?: string;
327
- webhookSecret?: string;
328
354
  /** Register on a gateway you do not own anyway, on the terms `bankTransfer` sets out */
329
355
  allowPublicGateway?: boolean;
330
356
  /** What `Leg.rail` reads, for a shop running more than one account */
@@ -345,7 +371,6 @@ interface LightningRailConfig {
345
371
  */
346
372
  idempotencyKey?: (order: Order) => string | undefined;
347
373
  webhookUrl?: string;
348
- webhookSecret?: string;
349
374
  /** What `Leg.rail` reads, for a shop running more than one wallet */
350
375
  name?: string;
351
376
  }
@@ -361,7 +386,6 @@ interface BlindLightningRailConfig {
361
386
  /** Only a watched leg has anywhere to carry this */
362
387
  sealed?: (order: Order) => string | Promise<string>;
363
388
  webhookUrl?: string;
364
- webhookSecret?: string;
365
389
  /**
366
390
  * Where your own `lightningVerifyEndpoint` is mounted, and the secret it
367
391
  * unseals with. Set both and the gateway is handed your URL rather than the
@@ -397,4 +421,4 @@ declare function lightningRail(config: LightningRailConfig): Rail;
397
421
  */
398
422
  declare function blindLightningRail(config: BlindLightningRailConfig): Rail;
399
423
 
400
- export { type BankRailConfig as B, type CreatePaymentParams as C, type FollowOptions as F, type Leg as L, type Order as O, type Payment as P, type Quote as Q, type Rail as R, ThunderBridge as T, type WalletFailure as W, type TriggerEvent as a, type CreateOptions as b, type CreateQuoteParams as c, type LightningRailConfig as d, type PaymentKind as e, type PaymentStatus as f, type ThunderBridgeOptions as g, type WaitOptions as h, type WalletReason as i, type WatchPaymentParams as j, bankRail as k, lightningRail as l, type BlindLightningRailConfig as m, blindLightningRail as n };
424
+ export { type BankRailConfig as B, type CreatePaymentParams as C, type FollowOptions as F, type Leg as L, type Order as O, type Payment as P, type Quote as Q, type Rail as R, type Settlement as S, ThunderBridge as T, type WatchPaymentParams as W, type ThunderBridgeOptions as a, type TriggerEvent as b, type WaitOptions as c, type WalletFailure as d, type CreateOptions as e, type CreateQuoteParams as f, type LightningRailConfig as g, type PaymentKind as h, type PaymentStatus as i, type WalletReason as j, bankRail as k, lightningRail as l, type BlindLightningRailConfig as m, blindLightningRail as n };
@@ -23,7 +23,6 @@ interface CreatePaymentParams {
23
23
  lnAddresses: string[];
24
24
  amountMsat: number;
25
25
  webhookUrl?: string;
26
- webhookSecret?: string;
27
26
  }
28
27
  /**
29
28
  * `lnAddresses` is the same priority list `createPayment` takes, and quoting it
@@ -78,7 +77,6 @@ interface WatchPaymentParams {
78
77
  trigger?: string;
79
78
  sealed?: string;
80
79
  webhookUrl?: string;
81
- webhookSecret?: string;
82
80
  }
83
81
  /** Why one wallet in the list could not be used */
84
82
  type WalletReason = "address-unusable" | "unreachable" | "amount-not-accepted" | "cannot-prove-delivery" | "invoice-refused";
@@ -86,6 +84,17 @@ interface WalletFailure {
86
84
  address: string;
87
85
  reason: WalletReason;
88
86
  }
87
+ /**
88
+ * What a delivery carries. Everything needed to act on a settlement and to check
89
+ * it, and nothing else, so a retry is the same size every time
90
+ */
91
+ interface Settlement {
92
+ id: string;
93
+ status: PaymentStatus;
94
+ paymentHash: string;
95
+ preimage: string | null;
96
+ settledAt: number;
97
+ }
89
98
 
90
99
  interface ThunderBridgeOptions {
91
100
  /**
@@ -101,6 +110,13 @@ interface ThunderBridgeOptions {
101
110
  * through a ticket
102
111
  */
103
112
  token?: string;
113
+ /**
114
+ * The same long lived server side secret your rail derives its preimages from.
115
+ * Given here, every call carries a signature the gateway reads as your identity,
116
+ * so a payment you create is handed back to you and to nobody else. Withheld,
117
+ * you are anonymous and any holder of an id can read what it names
118
+ */
119
+ secret?: string;
104
120
  }
105
121
  interface WaitOptions {
106
122
  /** Give up when this aborts, `AbortSignal.timeout(ms)` covers the usual case */
@@ -159,7 +175,9 @@ declare class ThunderBridge {
159
175
  private readonly baseUrl;
160
176
  private readonly verify;
161
177
  private readonly token;
178
+ private readonly secret;
162
179
  private strangers;
180
+ private speaks;
163
181
  constructor(baseUrl: string, options?: ThunderBridgeOptions);
164
182
  /**
165
183
  * Whether a token was given, which is what makes an instance yours: a gateway
@@ -262,6 +280,14 @@ declare class ThunderBridge {
262
280
  * the watcher needs goes in `sealed`, which the gateway cannot read
263
281
  */
264
282
  watchPayment(params: WatchPaymentParams): Promise<TriggerEvent>;
283
+ /**
284
+ * What this payment is called, which you can work out before any gateway has
285
+ * heard of it. Every gateway you hand the same invoice to answers with the same
286
+ * name, so watching at several of them adds up to one payment rather than
287
+ * several, and no gateway's key is in the answer. Null when no secret was given,
288
+ * because then the gateway names the payment and only it can
289
+ */
290
+ nameFor(paymentHash: string): Promise<string | null>;
265
291
  /**
266
292
  * Follow every payment made to one trigger, replayed from the recent ones on
267
293
  * connect and then live, reconnecting on its own until the returned function
@@ -272,6 +298,7 @@ declare class ThunderBridge {
272
298
  private wsTicket;
273
299
  private sending;
274
300
  private reading;
301
+ private speaking;
275
302
  private proven;
276
303
  private checked;
277
304
  }
@@ -324,7 +351,6 @@ interface BankRailConfig {
324
351
  /** Up to ten digits, for accounting systems that still want one */
325
352
  variableSymbol?: (order: Order) => string | undefined;
326
353
  webhookUrl?: string;
327
- webhookSecret?: string;
328
354
  /** Register on a gateway you do not own anyway, on the terms `bankTransfer` sets out */
329
355
  allowPublicGateway?: boolean;
330
356
  /** What `Leg.rail` reads, for a shop running more than one account */
@@ -345,7 +371,6 @@ interface LightningRailConfig {
345
371
  */
346
372
  idempotencyKey?: (order: Order) => string | undefined;
347
373
  webhookUrl?: string;
348
- webhookSecret?: string;
349
374
  /** What `Leg.rail` reads, for a shop running more than one wallet */
350
375
  name?: string;
351
376
  }
@@ -361,7 +386,6 @@ interface BlindLightningRailConfig {
361
386
  /** Only a watched leg has anywhere to carry this */
362
387
  sealed?: (order: Order) => string | Promise<string>;
363
388
  webhookUrl?: string;
364
- webhookSecret?: string;
365
389
  /**
366
390
  * Where your own `lightningVerifyEndpoint` is mounted, and the secret it
367
391
  * unseals with. Set both and the gateway is handed your URL rather than the
@@ -397,4 +421,4 @@ declare function lightningRail(config: LightningRailConfig): Rail;
397
421
  */
398
422
  declare function blindLightningRail(config: BlindLightningRailConfig): Rail;
399
423
 
400
- export { type BankRailConfig as B, type CreatePaymentParams as C, type FollowOptions as F, type Leg as L, type Order as O, type Payment as P, type Quote as Q, type Rail as R, ThunderBridge as T, type WalletFailure as W, type TriggerEvent as a, type CreateOptions as b, type CreateQuoteParams as c, type LightningRailConfig as d, type PaymentKind as e, type PaymentStatus as f, type ThunderBridgeOptions as g, type WaitOptions as h, type WalletReason as i, type WatchPaymentParams as j, bankRail as k, lightningRail as l, type BlindLightningRailConfig as m, blindLightningRail as n };
424
+ export { type BankRailConfig as B, type CreatePaymentParams as C, type FollowOptions as F, type Leg as L, type Order as O, type Payment as P, type Quote as Q, type Rail as R, type Settlement as S, ThunderBridge as T, type WatchPaymentParams as W, type ThunderBridgeOptions as a, type TriggerEvent as b, type WaitOptions as c, type WalletFailure as d, type CreateOptions as e, type CreateQuoteParams as f, type LightningRailConfig as g, type PaymentKind as h, type PaymentStatus as i, type WalletReason as j, bankRail as k, lightningRail as l, type BlindLightningRailConfig as m, blindLightningRail as n };
package/dist/server.cjs CHANGED
@@ -926,8 +926,7 @@ function blindLightningRail(config) {
926
926
  expiresAt: resolved2.expiresAt,
927
927
  trigger: config.trigger,
928
928
  sealed: await config.sealed?.(order),
929
- webhookUrl: config.webhookUrl,
930
- webhookSecret: config.webhookSecret
929
+ webhookUrl: config.webhookUrl
931
930
  });
932
931
  return {
933
932
  id: watched.id,
package/dist/server.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as ThunderBridge } from './rail-J8QoYbSr.cjs';
2
- export { m as BlindLightningRailConfig, n as blindLightningRail } from './rail-J8QoYbSr.cjs';
1
+ import { T as ThunderBridge } from './rail-CL9QkiHo.cjs';
2
+ export { m as BlindLightningRailConfig, n as blindLightningRail } from './rail-CL9QkiHo.cjs';
3
3
 
4
4
  interface TriggerConfig {
5
5
  /** The gateway that quotes the addresses and mints the invoice */
package/dist/server.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as ThunderBridge } from './rail-J8QoYbSr.js';
2
- export { m as BlindLightningRailConfig, n as blindLightningRail } from './rail-J8QoYbSr.js';
1
+ import { T as ThunderBridge } from './rail-CL9QkiHo.js';
2
+ export { m as BlindLightningRailConfig, n as blindLightningRail } from './rail-CL9QkiHo.js';
3
3
 
4
4
  interface TriggerConfig {
5
5
  /** The gateway that quotes the addresses and mints the invoice */
package/dist/server.js CHANGED
@@ -887,8 +887,7 @@ function blindLightningRail(config) {
887
887
  expiresAt: resolved2.expiresAt,
888
888
  trigger: config.trigger,
889
889
  sealed: await config.sealed?.(order),
890
- webhookUrl: config.webhookUrl,
891
- webhookSecret: config.webhookSecret
890
+ webhookUrl: config.webhookUrl
892
891
  });
893
892
  return {
894
893
  id: watched.id,
package/openapi.yaml CHANGED
@@ -2,7 +2,7 @@ openapi: 3.1.0
2
2
 
3
3
  info:
4
4
  title: thunder-bridge, the endpoint your own service serves
5
- version: 0.8.1
5
+ version: 1.0.0
6
6
  license:
7
7
  name: MIT
8
8
  identifier: MIT
@@ -207,6 +207,48 @@ paths:
207
207
  schema:
208
208
  $ref: "#/components/schemas/unsettled"
209
209
 
210
+ post:
211
+ tags: [bank-transfer]
212
+ operationId: answerVerifyChallenge
213
+ summary: Agree to be polled, before the gateway will watch anything pointed here
214
+ description: |
215
+ The gateway will not poll a URL a caller merely named. It POSTs a nonce here first and
216
+ watches nothing unless this endpoint hands the same nonce back, which is how a caller
217
+ shows the endpoint consented to the traffic rather than being volunteered for it. A
218
+ registration whose verify URL will not answer is refused with `verify-unconsented`.
219
+
220
+ Every verify endpoint the SDK builds answers this as its first line, before it parses
221
+ its own query, so `bankVerifyEndpoint`, `lightningVerifyEndpoint` and anything wrapping
222
+ `answerVerifyChallengeRequest` already do it.
223
+
224
+ There is nothing to sign. Echoing a nonce grants the asker nothing, so this holds no
225
+ secret and checks none.
226
+ requestBody:
227
+ required: true
228
+ content:
229
+ application/json:
230
+ schema:
231
+ type: object
232
+ properties:
233
+ type:
234
+ type: string
235
+ enum: [verify-challenge]
236
+ nonce:
237
+ type: string
238
+ pattern: "^[0-9a-f]{64}$"
239
+ required: [type, nonce]
240
+ responses:
241
+ "200":
242
+ description: The same nonce, and nothing else.
243
+ content:
244
+ application/json:
245
+ schema:
246
+ type: object
247
+ properties:
248
+ nonce:
249
+ type: string
250
+ required: [nonce]
251
+
210
252
  components:
211
253
  schemas:
212
254
  settlement:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thunder-bridge",
3
- "version": "0.8.10",
3
+ "version": "1.0.0",
4
4
  "description": "Trustless JavaScript client for the Thunder Bridge Lightning payment gateway. Proves the invoice came from your own wallet before the payer sees it.",
5
5
  "author": "i-am-fatik",
6
6
  "homepage": "https://agora.gripe/en/tools/thunder-bridge",