thunder-bridge 2.2.0 → 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
@@ -152,12 +152,12 @@ preimage, and which side does the checking.
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
 
@@ -108,7 +108,7 @@ interface NwcRailConfig extends RailConfig {
108
108
  amount?: (order: Order) => Amount;
109
109
  /** Where the default conversion gets its rate, the median of four venues by default */
110
110
  rate?: Ticker;
111
- /** Where `nwcVerifyEndpoint` is mounted, and the secret the hash is sealed with */
111
+ /** Where `serve.nwcVerify` is mounted, and the secret the hash is sealed with */
112
112
  verifyThrough: {
113
113
  endpoint: string;
114
114
  secret: string;
@@ -931,9 +931,13 @@ interface Credit {
931
931
  /**
932
932
  * Recent credits on one account, oldest or newest first, it makes no difference.
933
933
  * This is the whole plugin seam: a bank is a function of this shape, and
934
- * `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
935
937
  */
936
- type Statement = (sinceUnix: number) => Promise<Credit[]>;
938
+ type Statement = ((sinceUnix: number) => Promise<Credit[]>) & {
939
+ readonly freshEverySecs?: number;
940
+ };
937
941
  /** One transfer to ask for: what is owed, where it lands, and where its arrival is read back from */
938
942
  interface BankTransferParams {
939
943
  /**
@@ -1018,7 +1022,9 @@ interface BankVerifyConfig {
1018
1022
  * How often you want the gateway to ask, in seconds. It goes out as
1019
1023
  * `Cache-Control: max-age`, so the pace is yours to set rather than the
1020
1024
  * gateway's, and a bank that updates once a minute should say so instead of
1021
- * 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
1022
1028
  */
1023
1029
  pollEverySecs?: number;
1024
1030
  }
@@ -108,7 +108,7 @@ interface NwcRailConfig extends RailConfig {
108
108
  amount?: (order: Order) => Amount;
109
109
  /** Where the default conversion gets its rate, the median of four venues by default */
110
110
  rate?: Ticker;
111
- /** Where `nwcVerifyEndpoint` is mounted, and the secret the hash is sealed with */
111
+ /** Where `serve.nwcVerify` is mounted, and the secret the hash is sealed with */
112
112
  verifyThrough: {
113
113
  endpoint: string;
114
114
  secret: string;
@@ -931,9 +931,13 @@ interface Credit {
931
931
  /**
932
932
  * Recent credits on one account, oldest or newest first, it makes no difference.
933
933
  * This is the whole plugin seam: a bank is a function of this shape, and
934
- * `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
935
937
  */
936
- type Statement = (sinceUnix: number) => Promise<Credit[]>;
938
+ type Statement = ((sinceUnix: number) => Promise<Credit[]>) & {
939
+ readonly freshEverySecs?: number;
940
+ };
937
941
  /** One transfer to ask for: what is owed, where it lands, and where its arrival is read back from */
938
942
  interface BankTransferParams {
939
943
  /**
@@ -1018,7 +1022,9 @@ interface BankVerifyConfig {
1018
1022
  * How often you want the gateway to ask, in seconds. It goes out as
1019
1023
  * `Cache-Control: max-age`, so the pace is yours to set rather than the
1020
1024
  * gateway's, and a bank that updates once a minute should say so instead of
1021
- * 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
1022
1028
  */
1023
1029
  pollEverySecs?: number;
1024
1030
  }
package/dist/bank.cjs CHANGED
@@ -250,7 +250,7 @@ function fioStatement(config) {
250
250
  const paceMs = tokenWindowMs / usedAt.size;
251
251
  let lastRead = Number.NEGATIVE_INFINITY;
252
252
  let credits = [];
253
- return async (sinceUnix) => {
253
+ const read = async (sinceUnix) => {
254
254
  const now = Date.now();
255
255
  if (now - lastRead < paceMs) {
256
256
  return credits;
@@ -276,10 +276,17 @@ function fioStatement(config) {
276
276
  if (!answer.ok) {
277
277
  throw new Error(`fio answered ${answer.status} reading the statement`);
278
278
  }
279
- const read = await answer.json();
280
- credits = (read.accountStatement?.transactionList?.transaction ?? []).filter(isCredit).map(asCredit);
279
+ const statement = await answer.json();
280
+ const reads = statement.accountStatement?.info?.iban;
281
+ if (config.iban !== void 0 && accountOf(reads ?? "") !== accountOf(config.iban)) {
282
+ throw new Error(
283
+ `a fio token reads ${reads ?? "an account it does not name"}, not ${config.iban}`
284
+ );
285
+ }
286
+ credits = (statement.accountStatement?.transactionList?.transaction ?? []).filter(isCredit).map(asCredit);
281
287
  return credits;
282
288
  };
289
+ return Object.assign(read, { freshEverySecs: Math.ceil(paceMs / MILLIS) });
283
290
  }
284
291
  function longestUnused(usedAt) {
285
292
  let token = "";
package/dist/bank.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Statement } from './bank-Bg6RjuO-.cjs';
2
- export { B as BankAgentConfig, a as BankOrder, b as BankTransfer, c as BankTransferParams, d as BankVerifyConfig, C as Credit, e as bankAgent } from './bank-Bg6RjuO-.cjs';
1
+ import { S as Statement } from './bank-DvcV85sa.cjs';
2
+ export { B as BankAgentConfig, a as BankOrder, b as BankTransfer, c as BankTransferParams, d as BankVerifyConfig, C as Credit, e as bankAgent } from './bank-DvcV85sa.cjs';
3
3
  import './qr-CF-YeXU1.cjs';
4
4
  import './types-DYZ9EkmJ.cjs';
5
5
 
@@ -23,6 +23,12 @@ interface FioConfig {
23
23
  * stays up
24
24
  */
25
25
  minIntervalSecs?: number;
26
+ /**
27
+ * The account every token has to read. Given, a read by a token that belongs to
28
+ * another account throws instead of lending that account's credits to this one,
29
+ * which is the mistake several tokens make easy
30
+ */
31
+ iban?: string;
26
32
  /** Override to point at a mock */
27
33
  baseUrl?: string;
28
34
  }
package/dist/bank.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Statement } from './bank-B5MxT_6u.js';
2
- export { B as BankAgentConfig, a as BankOrder, b as BankTransfer, c as BankTransferParams, d as BankVerifyConfig, C as Credit, e as bankAgent } from './bank-B5MxT_6u.js';
1
+ import { S as Statement } from './bank-BgA45yOU.js';
2
+ export { B as BankAgentConfig, a as BankOrder, b as BankTransfer, c as BankTransferParams, d as BankVerifyConfig, C as Credit, e as bankAgent } from './bank-BgA45yOU.js';
3
3
  import './qr-CF-YeXU1.js';
4
4
  import './types-DYZ9EkmJ.js';
5
5
 
@@ -23,6 +23,12 @@ interface FioConfig {
23
23
  * stays up
24
24
  */
25
25
  minIntervalSecs?: number;
26
+ /**
27
+ * The account every token has to read. Given, a read by a token that belongs to
28
+ * another account throws instead of lending that account's credits to this one,
29
+ * which is the mistake several tokens make easy
30
+ */
31
+ iban?: string;
26
32
  /** Override to point at a mock */
27
33
  baseUrl?: string;
28
34
  }
package/dist/bank.js CHANGED
@@ -223,7 +223,7 @@ function fioStatement(config) {
223
223
  const paceMs = tokenWindowMs / usedAt.size;
224
224
  let lastRead = Number.NEGATIVE_INFINITY;
225
225
  let credits = [];
226
- return async (sinceUnix) => {
226
+ const read = async (sinceUnix) => {
227
227
  const now = Date.now();
228
228
  if (now - lastRead < paceMs) {
229
229
  return credits;
@@ -249,10 +249,17 @@ function fioStatement(config) {
249
249
  if (!answer.ok) {
250
250
  throw new Error(`fio answered ${answer.status} reading the statement`);
251
251
  }
252
- const read = await answer.json();
253
- credits = (read.accountStatement?.transactionList?.transaction ?? []).filter(isCredit).map(asCredit);
252
+ const statement = await answer.json();
253
+ const reads = statement.accountStatement?.info?.iban;
254
+ if (config.iban !== void 0 && accountOf(reads ?? "") !== accountOf(config.iban)) {
255
+ throw new Error(
256
+ `a fio token reads ${reads ?? "an account it does not name"}, not ${config.iban}`
257
+ );
258
+ }
259
+ credits = (statement.accountStatement?.transactionList?.transaction ?? []).filter(isCredit).map(asCredit);
254
260
  return credits;
255
261
  };
262
+ return Object.assign(read, { freshEverySecs: Math.ceil(paceMs / MILLIS) });
256
263
  }
257
264
  function longestUnused(usedAt) {
258
265
  let token = "";
package/dist/index.cjs CHANGED
@@ -2049,7 +2049,7 @@ function bankVerifyEndpoint(config) {
2049
2049
  throw new Error(`${config.iban} is not an IBAN, so this endpoint answers for no account`);
2050
2050
  }
2051
2051
  const paced = {
2052
- "cache-control": `max-age=${config.pollEverySecs ?? DEFAULT_POLL_EVERY_SECS}`
2052
+ "cache-control": `max-age=${config.pollEverySecs ?? config.statement.freshEverySecs ?? DEFAULT_POLL_EVERY_SECS}`
2053
2053
  };
2054
2054
  return async (request) => {
2055
2055
  const consented = await answerVerifyChallenge(request);
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { R as Resolved } from './qr-CF-YeXU1.cjs';
2
- import { T as ThunderBridge, r as ThunderBridgeOptions, W as WaitOptions } from './bank-Bg6RjuO-.cjs';
3
- export { A as AttendOptions, s as BankRailConfig, d as BankVerifyConfig, t as BlindLightningRailConfig, u as CreateOptions, F as FollowOptions, H as Handler, L as Leg, v as LightningRailConfig, w as LightningVerifyConfig, M as Minted, N as NwcConnection, h as NwcRailConfig, i as NwcVerifyConfig, O as Order, P as PaymentRequest, x as PaymentRequestInit, y as PaymentRequestOptions, z as Provable, D as Proven, R as Rail, E as RailConfig, G as Rails, I as Range, J as Relayed, K as SelfConsistent, Q as Send, U as Serve, V as TicketOptions, X as TriggerConfig, Y as WatchTicketConfig, Z as WebhookCredential, _ as WebhookHandlers, $ as WebhookOptions, a0 as WrapAllowance, a1 as agreesWithItself, a2 as answerVerifyChallenge, a3 as carriesProof, a4 as invoiceFrom, a5 as proveOrigin, a6 as proveSettlement, a7 as proveWrapped, a8 as relayedVerifyUrl, a9 as wrapFeeCeiling } from './bank-Bg6RjuO-.cjs';
2
+ import { T as ThunderBridge, r as ThunderBridgeOptions, W as WaitOptions } from './bank-DvcV85sa.cjs';
3
+ export { A as AttendOptions, s as BankRailConfig, d as BankVerifyConfig, t as BlindLightningRailConfig, u as CreateOptions, F as FollowOptions, H as Handler, L as Leg, v as LightningRailConfig, w as LightningVerifyConfig, M as Minted, N as NwcConnection, h as NwcRailConfig, i as NwcVerifyConfig, O as Order, P as PaymentRequest, x as PaymentRequestInit, y as PaymentRequestOptions, z as Provable, D as Proven, R as Rail, E as RailConfig, G as Rails, I as Range, J as Relayed, K as SelfConsistent, Q as Send, U as Serve, V as TicketOptions, X as TriggerConfig, Y as WatchTicketConfig, Z as WebhookCredential, _ as WebhookHandlers, $ as WebhookOptions, a0 as WrapAllowance, a1 as agreesWithItself, a2 as answerVerifyChallenge, a3 as carriesProof, a4 as invoiceFrom, a5 as proveOrigin, a6 as proveSettlement, a7 as proveWrapped, a8 as relayedVerifyUrl, a9 as wrapFeeCeiling } from './bank-DvcV85sa.cjs';
4
4
  import { H as Handover, P as Payment, e as Held } from './types-DYZ9EkmJ.cjs';
5
5
  export { A as Amount, C as Charge, F as FiatOptions, f as MintedPayment, g as Msat, h as PaymentStatus, i as Priced, Q as Quote, S as Settlement, j as SocketTicket, W as WalletFailure, l as WalletReason, n as WatchedPayment, o as fiat, p as msat, s as sats } from './types-DYZ9EkmJ.cjs';
6
6
  import { G as GatewayCheatError } from './errors-DJmsalYZ.cjs';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { R as Resolved } from './qr-CF-YeXU1.js';
2
- import { T as ThunderBridge, r as ThunderBridgeOptions, W as WaitOptions } from './bank-B5MxT_6u.js';
3
- export { A as AttendOptions, s as BankRailConfig, d as BankVerifyConfig, t as BlindLightningRailConfig, u as CreateOptions, F as FollowOptions, H as Handler, L as Leg, v as LightningRailConfig, w as LightningVerifyConfig, M as Minted, N as NwcConnection, h as NwcRailConfig, i as NwcVerifyConfig, O as Order, P as PaymentRequest, x as PaymentRequestInit, y as PaymentRequestOptions, z as Provable, D as Proven, R as Rail, E as RailConfig, G as Rails, I as Range, J as Relayed, K as SelfConsistent, Q as Send, U as Serve, V as TicketOptions, X as TriggerConfig, Y as WatchTicketConfig, Z as WebhookCredential, _ as WebhookHandlers, $ as WebhookOptions, a0 as WrapAllowance, a1 as agreesWithItself, a2 as answerVerifyChallenge, a3 as carriesProof, a4 as invoiceFrom, a5 as proveOrigin, a6 as proveSettlement, a7 as proveWrapped, a8 as relayedVerifyUrl, a9 as wrapFeeCeiling } from './bank-B5MxT_6u.js';
2
+ import { T as ThunderBridge, r as ThunderBridgeOptions, W as WaitOptions } from './bank-BgA45yOU.js';
3
+ export { A as AttendOptions, s as BankRailConfig, d as BankVerifyConfig, t as BlindLightningRailConfig, u as CreateOptions, F as FollowOptions, H as Handler, L as Leg, v as LightningRailConfig, w as LightningVerifyConfig, M as Minted, N as NwcConnection, h as NwcRailConfig, i as NwcVerifyConfig, O as Order, P as PaymentRequest, x as PaymentRequestInit, y as PaymentRequestOptions, z as Provable, D as Proven, R as Rail, E as RailConfig, G as Rails, I as Range, J as Relayed, K as SelfConsistent, Q as Send, U as Serve, V as TicketOptions, X as TriggerConfig, Y as WatchTicketConfig, Z as WebhookCredential, _ as WebhookHandlers, $ as WebhookOptions, a0 as WrapAllowance, a1 as agreesWithItself, a2 as answerVerifyChallenge, a3 as carriesProof, a4 as invoiceFrom, a5 as proveOrigin, a6 as proveSettlement, a7 as proveWrapped, a8 as relayedVerifyUrl, a9 as wrapFeeCeiling } from './bank-BgA45yOU.js';
4
4
  import { H as Handover, P as Payment, e as Held } from './types-DYZ9EkmJ.js';
5
5
  export { A as Amount, C as Charge, F as FiatOptions, f as MintedPayment, g as Msat, h as PaymentStatus, i as Priced, Q as Quote, S as Settlement, j as SocketTicket, W as WalletFailure, l as WalletReason, n as WatchedPayment, o as fiat, p as msat, s as sats } from './types-DYZ9EkmJ.js';
6
6
  import { G as GatewayCheatError } from './errors-VX0R18oE.js';
package/dist/index.js CHANGED
@@ -1989,7 +1989,7 @@ function bankVerifyEndpoint(config) {
1989
1989
  throw new Error(`${config.iban} is not an IBAN, so this endpoint answers for no account`);
1990
1990
  }
1991
1991
  const paced = {
1992
- "cache-control": `max-age=${config.pollEverySecs ?? DEFAULT_POLL_EVERY_SECS}`
1992
+ "cache-control": `max-age=${config.pollEverySecs ?? config.statement.freshEverySecs ?? DEFAULT_POLL_EVERY_SECS}`
1993
1993
  };
1994
1994
  return async (request) => {
1995
1995
  const consented = await answerVerifyChallenge(request);
package/dist/nwc.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { n as nwcRail$1, f as nwcVerifyEndpoint$1 } from './bank-Bg6RjuO-.cjs';
2
- export { N as NwcConnection, g as NwcInvoice, h as NwcRailConfig, i as NwcVerifyConfig, j as askWallet, k as nwcConnection, l as nwcHoldInvoice, m as nwcInvoice, o as nwcPay, p as nwcSettlement, q as nwcVerifyUrl } from './bank-Bg6RjuO-.cjs';
1
+ import { n as nwcRail$1, f as nwcVerifyEndpoint$1 } from './bank-DvcV85sa.cjs';
2
+ export { N as NwcConnection, g as NwcInvoice, h as NwcRailConfig, i as NwcVerifyConfig, j as askWallet, k as nwcConnection, l as nwcHoldInvoice, m as nwcInvoice, o as nwcPay, p as nwcSettlement, q as nwcVerifyUrl } from './bank-DvcV85sa.cjs';
3
3
  import './qr-CF-YeXU1.cjs';
4
4
  import './types-DYZ9EkmJ.cjs';
5
5
 
package/dist/nwc.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { n as nwcRail$1, f as nwcVerifyEndpoint$1 } from './bank-B5MxT_6u.js';
2
- export { N as NwcConnection, g as NwcInvoice, h as NwcRailConfig, i as NwcVerifyConfig, j as askWallet, k as nwcConnection, l as nwcHoldInvoice, m as nwcInvoice, o as nwcPay, p as nwcSettlement, q as nwcVerifyUrl } from './bank-B5MxT_6u.js';
1
+ import { n as nwcRail$1, f as nwcVerifyEndpoint$1 } from './bank-BgA45yOU.js';
2
+ export { N as NwcConnection, g as NwcInvoice, h as NwcRailConfig, i as NwcVerifyConfig, j as askWallet, k as nwcConnection, l as nwcHoldInvoice, m as nwcInvoice, o as nwcPay, p as nwcSettlement, q as nwcVerifyUrl } from './bank-BgA45yOU.js';
3
3
  import './qr-CF-YeXU1.js';
4
4
  import './types-DYZ9EkmJ.js';
5
5
 
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: 2.2.0
5
+ version: 2.2.1
6
6
  license:
7
7
  name: MIT
8
8
  identifier: MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thunder-bridge",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
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",