beignet 0.32.1 → 0.34.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.
Files changed (125) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/beignet-node.js +85 -20
  3. package/dist/cli/beignet-node.js.map +1 -1
  4. package/dist/cli/cli.js +22 -2
  5. package/dist/cli/cli.js.map +1 -1
  6. package/dist/cli/config.js +19 -1
  7. package/dist/cli/config.js.map +1 -1
  8. package/dist/cli/daemon-options.js +1 -0
  9. package/dist/cli/daemon-options.js.map +1 -1
  10. package/dist/cli/daemon.js +21 -3
  11. package/dist/cli/daemon.js.map +1 -1
  12. package/dist/cli/openapi.js +103 -3
  13. package/dist/cli/openapi.js.map +1 -1
  14. package/dist/cli/payment-queue.js +334 -60
  15. package/dist/cli/payment-queue.js.map +1 -1
  16. package/dist/cli/routes.js +4 -0
  17. package/dist/cli/routes.js.map +1 -1
  18. package/dist/cli/webhooks.js +254 -53
  19. package/dist/cli/webhooks.js.map +1 -1
  20. package/dist/daemon.js.map +1 -1
  21. package/dist/electrum/index.js +24 -32
  22. package/dist/electrum/index.js.map +1 -1
  23. package/dist/lightning/channel/channel-manager.js +32 -11
  24. package/dist/lightning/channel/channel-manager.js.map +1 -1
  25. package/dist/lightning/channel/channel.js +24 -2
  26. package/dist/lightning/channel/channel.js.map +1 -1
  27. package/dist/lightning/direct-funding/index.js +6 -2
  28. package/dist/lightning/direct-funding/index.js.map +1 -1
  29. package/dist/lightning/direct-funding/messages.js +49 -2
  30. package/dist/lightning/direct-funding/messages.js.map +1 -1
  31. package/dist/lightning/direct-funding/receiver/engine.js +65 -9
  32. package/dist/lightning/direct-funding/receiver/engine.js.map +1 -1
  33. package/dist/lightning/direct-funding/receiver/types.js.map +1 -1
  34. package/dist/lightning/direct-funding/receiver/verify.js +29 -1
  35. package/dist/lightning/direct-funding/receiver/verify.js.map +1 -1
  36. package/dist/lightning/direct-funding/requests.js +284 -17
  37. package/dist/lightning/direct-funding/requests.js.map +1 -1
  38. package/dist/lightning/direct-funding/sender/engine.js +8 -0
  39. package/dist/lightning/direct-funding/sender/engine.js.map +1 -1
  40. package/dist/lightning/direct-funding/sender/types.js.map +1 -1
  41. package/dist/lightning/direct-funding/sender/verify.js +17 -4
  42. package/dist/lightning/direct-funding/sender/verify.js.map +1 -1
  43. package/dist/lightning/direct-funding/types.js.map +1 -1
  44. package/dist/lightning/features/flags.js +11 -6
  45. package/dist/lightning/features/flags.js.map +1 -1
  46. package/dist/lightning/ffor/types.js +4 -4
  47. package/dist/lightning/liquidity/jit-receive.js +1 -0
  48. package/dist/lightning/liquidity/jit-receive.js.map +1 -1
  49. package/dist/lightning/message/channel-update.js +23 -8
  50. package/dist/lightning/message/channel-update.js.map +1 -1
  51. package/dist/lightning/node/config.js +1 -0
  52. package/dist/lightning/node/config.js.map +1 -1
  53. package/dist/lightning/node/lightning-node.js +253 -44
  54. package/dist/lightning/node/lightning-node.js.map +1 -1
  55. package/dist/lightning/node/types.js.map +1 -1
  56. package/dist/lightning/recovery/frame-reads.js +57 -0
  57. package/dist/lightning/recovery/frame-reads.js.map +1 -0
  58. package/dist/lightning/recovery/guardian-replication.js +95 -44
  59. package/dist/lightning/recovery/guardian-replication.js.map +1 -1
  60. package/dist/lightning/recovery/guardian-rotation.js +2 -5
  61. package/dist/lightning/recovery/guardian-rotation.js.map +1 -1
  62. package/dist/lightning/recovery/journal.js +8 -36
  63. package/dist/lightning/recovery/journal.js.map +1 -1
  64. package/dist/lightning/sqlite.js.map +1 -1
  65. package/dist/lightning/storage/index.js.map +1 -1
  66. package/dist/lightning/storage/serialization.js +6 -0
  67. package/dist/lightning/storage/serialization.js.map +1 -1
  68. package/dist/lightning/storage/sqlite-storage.js +64 -13
  69. package/dist/lightning/storage/sqlite-storage.js.map +1 -1
  70. package/dist/lightning/transport/peer-manager.js +67 -11
  71. package/dist/lightning/transport/peer-manager.js.map +1 -1
  72. package/dist/lightning/transport/peer.js +4 -2
  73. package/dist/lightning/transport/peer.js.map +1 -1
  74. package/dist/lightning/transport/wire-capture.js +6 -1
  75. package/dist/lightning/transport/wire-capture.js.map +1 -1
  76. package/dist/node.js.map +1 -1
  77. package/dist/shapes/electrum.js +7 -3
  78. package/dist/shapes/electrum.js.map +1 -1
  79. package/dist/types/cli/beignet-node.d.ts +18 -2
  80. package/dist/types/cli/config.d.ts +2 -0
  81. package/dist/types/cli/payment-queue.d.ts +126 -19
  82. package/dist/types/cli/routes.d.ts +12 -0
  83. package/dist/types/cli/types.d.ts +11 -0
  84. package/dist/types/cli/webhooks.d.ts +80 -3
  85. package/dist/types/daemon.d.ts +1 -1
  86. package/dist/types/electrum/index.d.ts +4 -1
  87. package/dist/types/lightning/channel/channel-manager.d.ts +12 -5
  88. package/dist/types/lightning/channel/channel.d.ts +13 -2
  89. package/dist/types/lightning/direct-funding/index.d.ts +3 -3
  90. package/dist/types/lightning/direct-funding/messages.d.ts +30 -0
  91. package/dist/types/lightning/direct-funding/receiver/engine.d.ts +8 -0
  92. package/dist/types/lightning/direct-funding/receiver/types.d.ts +22 -1
  93. package/dist/types/lightning/direct-funding/receiver/verify.d.ts +28 -0
  94. package/dist/types/lightning/direct-funding/requests.d.ts +80 -2
  95. package/dist/types/lightning/direct-funding/sender/types.d.ts +7 -0
  96. package/dist/types/lightning/direct-funding/types.d.ts +54 -0
  97. package/dist/types/lightning/features/flags.d.ts +6 -6
  98. package/dist/types/lightning/ffor/types.d.ts +4 -4
  99. package/dist/types/lightning/message/channel-update.d.ts +2 -0
  100. package/dist/types/lightning/node/config.d.ts +1 -0
  101. package/dist/types/lightning/node/events.d.ts +4 -3
  102. package/dist/types/lightning/node/lightning-node.d.ts +53 -11
  103. package/dist/types/lightning/node/payment-types.d.ts +8 -0
  104. package/dist/types/lightning/node/types.d.ts +21 -3
  105. package/dist/types/lightning/recovery/frame-reads.d.ts +25 -0
  106. package/dist/types/lightning/sqlite.d.ts +1 -1
  107. package/dist/types/lightning/storage/index.d.ts +1 -1
  108. package/dist/types/lightning/storage/serialization.d.ts +2 -0
  109. package/dist/types/lightning/storage/sqlite-storage.d.ts +33 -12
  110. package/dist/types/lightning/transport/peer-manager.d.ts +34 -0
  111. package/dist/types/lightning/transport/peer.d.ts +2 -1
  112. package/dist/types/lightning/transport/wire-capture.d.ts +2 -0
  113. package/dist/types/node.d.ts +1 -1
  114. package/dist/types/shapes/electrum.d.ts +6 -2
  115. package/dist/types/wallet/index.d.ts +45 -6
  116. package/dist/types/wallet/live-data.d.ts +22 -1
  117. package/dist/wallet/index.js +145 -18
  118. package/dist/wallet/index.js.map +1 -1
  119. package/dist/wallet/live-data.js +25 -11
  120. package/dist/wallet/live-data.js.map +1 -1
  121. package/docs/AI_AGENT_GUIDE.md +6 -3
  122. package/docs/FFOR-RESERVED-RETIREMENT.md +1 -1
  123. package/docs/specs/CONCURRENT-RECEIVE.md +5 -1
  124. package/docs/specs/ffor-offline-receive.md +4 -3
  125. package/package.json +2 -2
package/README.md CHANGED
@@ -576,7 +576,7 @@ The experimental concurrent profile keeps ordinary payments available
576
576
  within the channel's remaining capacity. `LightningNode.fforSync()` fetches paid
577
577
  slot receipts and redeems them while other vouchers remain live.
578
578
  `rescueFforEpoch()` syncs a connected concurrent book without retiring it.
579
- Feature bits 562/563 are advertised by default when their dependencies are enabled.
579
+ Feature bits 442/443 are advertised by default when their dependencies are enabled.
580
580
  See [concurrent receive and reserved retirement](docs/FFOR-RESERVED-RETIREMENT.md)
581
581
  for the version 1 and 2 contracts and storage requirements. The daemon enables
582
582
  advertisement with `BEIGNET_FFOR_CONCURRENT=true` and new concurrent settlement
@@ -377,27 +377,32 @@ function sentSats(info) {
377
377
  /**
378
378
  * A payment's amount as every public surface reports it (history, proof,
379
379
  * stats): an outgoing amount is what left the node, fees included, rounded
380
- * UP; an incoming amount rounds down, as the balance does (issue #1185).
381
- * Truncating the outgoing figure let a send paying 20,001.5 sats from a
382
- * 50,000 sat balance read 20,001 while the balance fell to 29,998. Rounding
383
- * up makes one send agree with the balance when the balance held whole sats
384
- * before it; sub-sat remainders across several sends can still differ from
385
- * the balance by a sat, which only msat figures reconcile exactly.
380
+ * UP; an incoming amount is what the node was credited, rounded down, as the
381
+ * balance does (issue #1185). Truncating the outgoing figure let a send
382
+ * paying 20,001.5 sats from a 50,000 sat balance read 20,001 while the
383
+ * balance fell to 29,998. Rounding up makes one send agree with the balance
384
+ * when the balance held whole sats before it; sub-sat remainders across
385
+ * several sends can still differ from the balance by a sat, which only msat
386
+ * figures reconcile exactly.
386
387
  */
387
388
  function paymentAmountSats(info) {
388
389
  return info.direction === types_6.PaymentDirection.OUTGOING
389
390
  ? sentSats(info) ?? spendLimitSats(info.amountMsat)
390
- : Number(info.amountMsat / 1000n);
391
+ : Number((info.receivedMsat ?? info.amountMsat) / 1000n);
391
392
  }
392
393
  /**
393
- * The routing fee a payment paid, in msat, or undefined when the record does
394
- * not say. An MPP record's route is its first part only, so its fee is what
395
- * left the node over what the invoice asked (#1008).
394
+ * The fee a payment paid, in msat, or undefined when the record does not
395
+ * say. An MPP record's route is its first part only, so its fee is what left
396
+ * the node over what the invoice asked (#1008). An incoming payment's fee is
397
+ * a JIT LSP's skim: what the invoice asked over what the node was credited.
396
398
  */
397
399
  function paymentFeeMsat(info) {
398
400
  if (info.sentMsat !== undefined && info.sentMsat >= info.amountMsat) {
399
401
  return info.sentMsat - info.amountMsat;
400
402
  }
403
+ if (info.receivedMsat !== undefined && info.receivedMsat < info.amountMsat) {
404
+ return info.amountMsat - info.receivedMsat;
405
+ }
401
406
  return info.route?.totalFeeMsat;
402
407
  }
403
408
  /**
@@ -596,11 +601,23 @@ const NETWORK_NAMES = ['mainnet', 'testnet', 'signet', 'regtest'];
596
601
  function unknownNetwork(network) {
597
602
  throw new errors_1.BeignetError('INVALID_PARAMS', `unknown network '${String(network)}'`);
598
603
  }
604
+ /**
605
+ * Mainnet and regtest are the servers the Bitkit app uses (bitkit-android,
606
+ * `Env.kt`), each with a certificate a public authority signed for its name,
607
+ * so `electrumTlsVerify` passes on them with no pin. They replace
608
+ * `fulcrum.bitkit.blocktank.to:8900`, whose certificate expired on May 10,
609
+ * 2026, and the plaintext `34.65.252.32:18483`, which serves the same regtest
610
+ * chain.
611
+ */
599
612
  const DEFAULT_ELECTRUM = {
600
- mainnet: { host: 'fulcrum.bitkit.blocktank.to', port: 8900, useTls: true },
613
+ mainnet: { host: 'bitkit.to', port: 9999, useTls: true },
601
614
  testnet: { host: 'electrum.blockstream.info', port: 60002, useTls: true },
602
615
  signet: { host: 'mempool.space', port: 60602, useTls: true },
603
- regtest: { host: '34.65.252.32', port: 18483, useTls: false }
616
+ regtest: {
617
+ host: 'electrs.bitkit.stag0.blocktank.to',
618
+ port: 9999,
619
+ useTls: true
620
+ }
604
621
  };
605
622
  /**
606
623
  * Resolve a host to a routable IPv4 address. Returns the host unchanged if it is
@@ -2121,6 +2138,7 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
2121
2138
  chainBackend: electrumBackend,
2122
2139
  feeEstimator: electrumBackend,
2123
2140
  logger: this.logger,
2141
+ wireTrace: opts.wireTrace,
2124
2142
  sweepDestinationScript,
2125
2143
  socks5Proxy,
2126
2144
  socks5ProxyScope,
@@ -2535,8 +2553,23 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
2535
2553
  });
2536
2554
  });
2537
2555
  // Forward peer events
2556
+ // Connects and disconnects are logged at info: a peer that evicts us
2557
+ // (eclair's max-no-channels) and the auto reconnect after it are
2558
+ // otherwise invisible at the level a daemon runs at.
2538
2559
  this.node.on('peer:connect', (pubkey) => {
2539
- this.log('debug', 'Peer connected', { pubkey });
2560
+ let direction;
2561
+ try {
2562
+ direction = this.node
2563
+ .getPeerManager()
2564
+ ?.getConnectionInfo(pubkey)?.direction;
2565
+ }
2566
+ catch {
2567
+ // The log line must not cost the gossip sync below.
2568
+ }
2569
+ this.log('info', 'Peer connected', {
2570
+ pubkey,
2571
+ ...(direction ? { direction } : {})
2572
+ });
2540
2573
  // Pull the gossip graph from the peer so we can route multi-hop payments
2541
2574
  // to destinations beyond our direct channels. Without this the graph
2542
2575
  // stays empty and only direct-peer payments work.
@@ -2570,8 +2603,20 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
2570
2603
  }
2571
2604
  this.emit('peer:connect', { pubkey });
2572
2605
  });
2573
- this.node.on('peer:disconnect', (pubkey) => {
2574
- this.log('debug', 'Peer disconnected', { pubkey });
2606
+ this.node.on('peer:disconnect', (pubkey, info) => {
2607
+ this.log('info', 'Peer disconnected', {
2608
+ pubkey,
2609
+ ...(info
2610
+ ? {
2611
+ closedBy: info.initiator === 'remote' ? 'peer' : 'us',
2612
+ ...(info.reason ? { reason: info.reason } : {}),
2613
+ direction: info.direction,
2614
+ ...(info.uptimeMs !== undefined
2615
+ ? { uptimeMs: info.uptimeMs }
2616
+ : {})
2617
+ }
2618
+ : {})
2619
+ });
2575
2620
  this.emit('peer:disconnect', { pubkey });
2576
2621
  });
2577
2622
  // The transport error that caused a disconnect (pong timeout, decrypt
@@ -2843,8 +2888,7 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
2843
2888
  timer = setTimeout(() => resolve('timeout'), BeignetNode.INITIAL_SYNC_TIMEOUT_MS);
2844
2889
  timer.unref?.();
2845
2890
  });
2846
- const attempt = this.wallet
2847
- .refreshWallet({})
2891
+ const attempt = (0, live_data_1.refreshLiveWallet)(this.wallet)
2848
2892
  .then((res) => {
2849
2893
  if (res.isErr()) {
2850
2894
  this.log('warn', 'Initial wallet refresh failed', {
@@ -5659,7 +5703,7 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
5659
5703
  });
5660
5704
  }
5661
5705
  async refreshWallet() {
5662
- const result = await this.wallet.refreshWallet({});
5706
+ const result = await (0, live_data_1.refreshLiveWallet)(this.wallet);
5663
5707
  if (result.isErr()) {
5664
5708
  throw new errors_1.BeignetError('REFRESH_FAILED', result.error.message);
5665
5709
  }
@@ -6944,6 +6988,8 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
6944
6988
  capacitySats: Number(ch.fundingSatoshis),
6945
6989
  isAnchor: (0, types_7.isAnchorChannel)(ch.channelType ?? null)
6946
6990
  };
6991
+ if (ch.preReestablishState)
6992
+ info.preReestablishState = ch.preReestablishState;
6947
6993
  // What the connected peer's init negotiated, read rather than guessed:
6948
6994
  // a client deciding whether to offer splice controls has no other way
6949
6995
  // to know, and reconstructing feature bits client-side is exactly the
@@ -7562,6 +7608,16 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
7562
7608
  listDirectFundingPayments() {
7563
7609
  return this.directFundingSender?.payments() ?? [];
7564
7610
  }
7611
+ /**
7612
+ * Every payment received against a request this node minted, newest first
7613
+ * (issue #1893). `receiptHash` is the `paymentHash` the request was minted
7614
+ * with. Kept after the request itself expires, so a client can still tell
7615
+ * its request was paid: a direct-funding payment settles no invoice and pays
7616
+ * no address, and REVERTED means the splice it went into was undone.
7617
+ */
7618
+ listDirectFundingReceived() {
7619
+ return this.node.getDirectFundingRequests()?.received() ?? [];
7620
+ }
7565
7621
  /**
7566
7622
  * Map a coded protocol refusal onto the daemon's error vocabulary. The codes
7567
7623
  * are carried through verbatim: they are what tells the app a refusal to
@@ -11208,7 +11264,10 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
11208
11264
  saveQueueEntry: (entry) => sqlite().saveQueueEntry(entry),
11209
11265
  updateQueueEntryStatus: (id, status, error, completedAt) => sqlite().updateQueueEntryStatus(id, status, error, completedAt),
11210
11266
  deleteQueueEntry: (id) => sqlite().deleteQueueEntry(id),
11211
- loadAllQueueEntries: () => sqlite().loadAllQueueEntries()
11267
+ loadAllQueueEntries: () => sqlite().loadAllQueueEntries(),
11268
+ loadActiveQueueEntries: () => sqlite().loadActiveQueueEntries(),
11269
+ loadQueueHistory: (limit, before) => sqlite().loadQueueHistory(limit, before),
11270
+ loadQueueEntry: (id) => sqlite().loadQueueEntry(id)
11212
11271
  };
11213
11272
  }
11214
11273
  enqueuePayment(bolt11, priority, opts) {
@@ -11217,6 +11276,12 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
11217
11276
  listQueue() {
11218
11277
  return this.getPaymentQueue().list();
11219
11278
  }
11279
+ getQueuedPayment(id) {
11280
+ return this.getPaymentQueue().get(id);
11281
+ }
11282
+ listQueueHistory(opts) {
11283
+ return this.getPaymentQueue().history(opts);
11284
+ }
11220
11285
  cancelQueuedPayment(id) {
11221
11286
  return this.getPaymentQueue().cancel(id);
11222
11287
  }
@@ -11258,7 +11323,7 @@ class BeignetNode extends typed_emitter_1.TypedEmitter {
11258
11323
  }
11259
11324
  else if (p.direction === 'INCOMING' && p.status === 'COMPLETED') {
11260
11325
  received++;
11261
- satsReceived += Number(p.amountMsat / 1000n);
11326
+ satsReceived += paymentAmountSats(p);
11262
11327
  }
11263
11328
  else if (p.status === 'FAILED') {
11264
11329
  failed++;