beignet 0.2.0 → 0.4.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 (215) hide show
  1. package/README.md +306 -1
  2. package/dist/cli/auth.js +238 -0
  3. package/dist/cli/auth.js.map +1 -0
  4. package/dist/cli/beignet-node.js +1034 -57
  5. package/dist/cli/beignet-node.js.map +1 -1
  6. package/dist/cli/cli.js +1257 -18
  7. package/dist/cli/cli.js.map +1 -1
  8. package/dist/cli/config.js +45 -1
  9. package/dist/cli/config.js.map +1 -1
  10. package/dist/cli/daemon.js +398 -38
  11. package/dist/cli/daemon.js.map +1 -1
  12. package/dist/cli/errors.js +2 -0
  13. package/dist/cli/errors.js.map +1 -1
  14. package/dist/cli/index.js +6 -1
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/openapi.js +1343 -89
  17. package/dist/cli/openapi.js.map +1 -1
  18. package/dist/cli/restore.js +89 -0
  19. package/dist/cli/restore.js.map +1 -0
  20. package/dist/cli/wallet-storage.js +34 -0
  21. package/dist/cli/wallet-storage.js.map +1 -0
  22. package/dist/electrum/index.js +107 -12
  23. package/dist/electrum/index.js.map +1 -1
  24. package/dist/index.js +1 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/lightning/advisor/fee-tuner.js +42 -0
  27. package/dist/lightning/advisor/fee-tuner.js.map +1 -0
  28. package/dist/lightning/advisor/index.js +9 -1
  29. package/dist/lightning/advisor/index.js.map +1 -1
  30. package/dist/lightning/advisor/rebalance-planner.js +55 -0
  31. package/dist/lightning/advisor/rebalance-planner.js.map +1 -0
  32. package/dist/lightning/backup/index.js +18 -0
  33. package/dist/lightning/backup/index.js.map +1 -0
  34. package/dist/lightning/backup/scb.js +42 -0
  35. package/dist/lightning/backup/scb.js.map +1 -0
  36. package/dist/lightning/chain/chain-monitor.js +27 -0
  37. package/dist/lightning/chain/chain-monitor.js.map +1 -1
  38. package/dist/lightning/chain/output-resolver.js +66 -15
  39. package/dist/lightning/chain/output-resolver.js.map +1 -1
  40. package/dist/lightning/chain/types.js +1 -0
  41. package/dist/lightning/chain/types.js.map +1 -1
  42. package/dist/lightning/channel/channel-manager.js +91 -24
  43. package/dist/lightning/channel/channel-manager.js.map +1 -1
  44. package/dist/lightning/channel/channel-state.js.map +1 -1
  45. package/dist/lightning/channel/channel.js +122 -4
  46. package/dist/lightning/channel/channel.js.map +1 -1
  47. package/dist/lightning/channel/commitment-builder.js +4 -7
  48. package/dist/lightning/channel/commitment-builder.js.map +1 -1
  49. package/dist/lightning/channel/dual-funding.js +6 -5
  50. package/dist/lightning/channel/dual-funding.js.map +1 -1
  51. package/dist/lightning/channel/splice-tx.js.map +1 -1
  52. package/dist/lightning/channel/types.js +3 -1
  53. package/dist/lightning/channel/types.js.map +1 -1
  54. package/dist/lightning/channel/validation.js +3 -3
  55. package/dist/lightning/channel/validation.js.map +1 -1
  56. package/dist/lightning/crypto/index.js +1 -0
  57. package/dist/lightning/crypto/index.js.map +1 -1
  58. package/dist/lightning/crypto/message-signing.js +116 -0
  59. package/dist/lightning/crypto/message-signing.js.map +1 -0
  60. package/dist/lightning/crypto/xchacha20poly1305.js +77 -0
  61. package/dist/lightning/crypto/xchacha20poly1305.js.map +1 -0
  62. package/dist/lightning/features/flags.js +1 -0
  63. package/dist/lightning/features/flags.js.map +1 -1
  64. package/dist/lightning/gossip/messages.js +37 -1
  65. package/dist/lightning/gossip/messages.js.map +1 -1
  66. package/dist/lightning/index.js +2 -1
  67. package/dist/lightning/index.js.map +1 -1
  68. package/dist/lightning/keys/signer.js +24 -3
  69. package/dist/lightning/keys/signer.js.map +1 -1
  70. package/dist/lightning/keys/wallet-keys.js +1 -0
  71. package/dist/lightning/keys/wallet-keys.js.map +1 -1
  72. package/dist/lightning/message/index.js +1 -0
  73. package/dist/lightning/message/index.js.map +1 -1
  74. package/dist/lightning/message/peer-storage.js +43 -0
  75. package/dist/lightning/message/peer-storage.js.map +1 -0
  76. package/dist/lightning/message/types.js +2 -0
  77. package/dist/lightning/message/types.js.map +1 -1
  78. package/dist/lightning/node/lightning-node.js +1593 -236
  79. package/dist/lightning/node/lightning-node.js.map +1 -1
  80. package/dist/lightning/node/types.js +18 -1
  81. package/dist/lightning/node/types.js.map +1 -1
  82. package/dist/lightning/offer/offer-manager.js +2 -5
  83. package/dist/lightning/offer/offer-manager.js.map +1 -1
  84. package/dist/lightning/offer/tlv.js +3 -1
  85. package/dist/lightning/offer/tlv.js.map +1 -1
  86. package/dist/lightning/storage/encryption.js +67 -0
  87. package/dist/lightning/storage/encryption.js.map +1 -0
  88. package/dist/lightning/storage/index.js +1 -0
  89. package/dist/lightning/storage/index.js.map +1 -1
  90. package/dist/lightning/storage/serialization.js +6 -2
  91. package/dist/lightning/storage/serialization.js.map +1 -1
  92. package/dist/lightning/storage/sqlite-storage.js +405 -33
  93. package/dist/lightning/storage/sqlite-storage.js.map +1 -1
  94. package/dist/lightning/watchtower/blob.js +221 -0
  95. package/dist/lightning/watchtower/blob.js.map +1 -0
  96. package/dist/lightning/watchtower/index.js +55 -0
  97. package/dist/lightning/watchtower/index.js.map +1 -0
  98. package/dist/lightning/watchtower/justice.js +272 -0
  99. package/dist/lightning/watchtower/justice.js.map +1 -0
  100. package/dist/lightning/watchtower/tower-connection.js +208 -0
  101. package/dist/lightning/watchtower/tower-connection.js.map +1 -0
  102. package/dist/lightning/watchtower/types.js +3 -0
  103. package/dist/lightning/watchtower/types.js.map +1 -0
  104. package/dist/lightning/watchtower/watchtower-client.js +472 -0
  105. package/dist/lightning/watchtower/watchtower-client.js.map +1 -0
  106. package/dist/lightning/watchtower/wtwire.js +201 -0
  107. package/dist/lightning/watchtower/wtwire.js.map +1 -0
  108. package/dist/logger.js +41 -0
  109. package/dist/logger.js.map +1 -0
  110. package/dist/shapes/electrum.js +32 -1
  111. package/dist/shapes/electrum.js.map +1 -1
  112. package/dist/shapes/wallet.js +11 -1
  113. package/dist/shapes/wallet.js.map +1 -1
  114. package/dist/transaction/index.js +163 -15
  115. package/dist/transaction/index.js.map +1 -1
  116. package/dist/types/cli/auth.d.ts +34 -0
  117. package/dist/types/cli/beignet-node.d.ts +148 -4
  118. package/dist/types/cli/daemon.d.ts +5 -0
  119. package/dist/types/cli/errors.d.ts +2 -0
  120. package/dist/types/cli/index.d.ts +1 -0
  121. package/dist/types/cli/restore.d.ts +10 -0
  122. package/dist/types/cli/types.d.ts +235 -1
  123. package/dist/types/cli/wallet-storage.d.ts +3 -0
  124. package/dist/types/electrum/index.d.ts +12 -0
  125. package/dist/types/electrum.js +1 -0
  126. package/dist/types/electrum.js.map +1 -1
  127. package/dist/types/index.d.ts +1 -0
  128. package/dist/types/lightning/advisor/fee-tuner.d.ts +20 -0
  129. package/dist/types/lightning/advisor/index.d.ts +4 -0
  130. package/dist/types/lightning/advisor/rebalance-planner.d.ts +12 -0
  131. package/dist/types/lightning/backup/index.d.ts +1 -0
  132. package/dist/types/lightning/backup/scb.d.ts +24 -0
  133. package/dist/types/lightning/chain/chain-monitor.d.ts +1 -0
  134. package/dist/types/lightning/chain/types.d.ts +1 -0
  135. package/dist/types/lightning/channel/channel-manager.d.ts +11 -0
  136. package/dist/types/lightning/channel/channel-state.d.ts +2 -0
  137. package/dist/types/lightning/channel/channel.d.ts +11 -5
  138. package/dist/types/lightning/channel/commitment-builder.d.ts +7 -7
  139. package/dist/types/lightning/channel/dual-funding.d.ts +2 -1
  140. package/dist/types/lightning/channel/splice-tx.d.ts +2 -2
  141. package/dist/types/lightning/channel/types.d.ts +2 -0
  142. package/dist/types/lightning/channel/validation.d.ts +1 -1
  143. package/dist/types/lightning/crypto/index.d.ts +1 -0
  144. package/dist/types/lightning/crypto/message-signing.d.ts +9 -0
  145. package/dist/types/lightning/crypto/xchacha20poly1305.d.ts +3 -0
  146. package/dist/types/lightning/features/flags.d.ts +1 -0
  147. package/dist/types/lightning/gossip/messages.d.ts +4 -0
  148. package/dist/types/lightning/index.d.ts +1 -0
  149. package/dist/types/lightning/keys/signer.d.ts +18 -1
  150. package/dist/types/lightning/keys/wallet-keys.d.ts +2 -1
  151. package/dist/types/lightning/message/index.d.ts +1 -0
  152. package/dist/types/lightning/message/peer-storage.d.ts +9 -0
  153. package/dist/types/lightning/message/types.d.ts +2 -0
  154. package/dist/types/lightning/node/lightning-node.d.ts +120 -4
  155. package/dist/types/lightning/node/types.d.ts +66 -1
  156. package/dist/types/lightning/storage/encryption.d.ts +11 -0
  157. package/dist/types/lightning/storage/index.d.ts +1 -0
  158. package/dist/types/lightning/storage/serialization.d.ts +2 -0
  159. package/dist/types/lightning/storage/sqlite-storage.d.ts +43 -3
  160. package/dist/types/lightning/storage/types.d.ts +62 -0
  161. package/dist/types/lightning/watchtower/blob.d.ts +46 -0
  162. package/dist/types/lightning/watchtower/index.d.ts +9 -0
  163. package/dist/types/lightning/watchtower/justice.d.ts +30 -0
  164. package/dist/types/lightning/watchtower/tower-connection.d.ts +34 -0
  165. package/dist/types/lightning/watchtower/types.d.ts +46 -0
  166. package/dist/types/lightning/watchtower/watchtower-client.d.ts +68 -0
  167. package/dist/types/lightning/watchtower/wtwire.d.ts +90 -0
  168. package/dist/types/logger.d.ts +17 -0
  169. package/dist/types/shapes/electrum.d.ts +3 -1
  170. package/dist/types/transaction/index.d.ts +6 -0
  171. package/dist/types/transaction.js.map +1 -1
  172. package/dist/types/types/electrum.d.ts +3 -2
  173. package/dist/types/types/transaction.d.ts +1 -1
  174. package/dist/types/types/wallet.d.ts +80 -4
  175. package/dist/types/utils/descriptors.d.ts +2 -0
  176. package/dist/types/utils/fees.d.ts +3 -0
  177. package/dist/types/utils/helpers.d.ts +3 -1
  178. package/dist/types/utils/index.d.ts +5 -0
  179. package/dist/types/utils/multisig.d.ts +29 -0
  180. package/dist/types/utils/transaction.d.ts +7 -0
  181. package/dist/types/utils/wallet-storage-encryption.d.ts +3 -0
  182. package/dist/types/utils/wallet.d.ts +1 -1
  183. package/dist/types/utils/watch-only.d.ts +12 -0
  184. package/dist/types/wallet/constants.d.ts +1 -0
  185. package/dist/types/wallet/index.d.ts +63 -4
  186. package/dist/types/wallet.js +3 -0
  187. package/dist/types/wallet.js.map +1 -1
  188. package/dist/utils/derivation-path.js +8 -7
  189. package/dist/utils/derivation-path.js.map +1 -1
  190. package/dist/utils/descriptors.js +56 -0
  191. package/dist/utils/descriptors.js.map +1 -0
  192. package/dist/utils/electrum.js +14 -4
  193. package/dist/utils/electrum.js.map +1 -1
  194. package/dist/utils/fees.js +19 -0
  195. package/dist/utils/fees.js.map +1 -0
  196. package/dist/utils/helpers.js +22 -5
  197. package/dist/utils/helpers.js.map +1 -1
  198. package/dist/utils/index.js +5 -0
  199. package/dist/utils/index.js.map +1 -1
  200. package/dist/utils/multisig.js +90 -0
  201. package/dist/utils/multisig.js.map +1 -0
  202. package/dist/utils/transaction.js +30 -3
  203. package/dist/utils/transaction.js.map +1 -1
  204. package/dist/utils/wallet-storage-encryption.js +45 -0
  205. package/dist/utils/wallet-storage-encryption.js.map +1 -0
  206. package/dist/utils/wallet.js +3 -1
  207. package/dist/utils/wallet.js.map +1 -1
  208. package/dist/utils/watch-only.js +102 -0
  209. package/dist/utils/watch-only.js.map +1 -0
  210. package/dist/wallet/constants.js +2 -1
  211. package/dist/wallet/constants.js.map +1 -1
  212. package/dist/wallet/index.js +810 -51
  213. package/dist/wallet/index.js.map +1 -1
  214. package/docs/ROADMAP.md +365 -0
  215. package/package.json +1 -1
@@ -0,0 +1,365 @@
1
+ # Beignet Feature Roadmap
2
+
3
+ Working checklist from the full feature-completeness review (2026-07-09). Items get
4
+ checked off as they land on master. Each substantive item gets its own branch + PR.
5
+ One milestone per session is the default pace; smaller milestones can share a session.
6
+
7
+ Legend: `[ ]` open, `[x]` done (PR #), `[~]` in progress, `[?]` needs a decision first.
8
+
9
+ ---
10
+
11
+ ## M0. Docs and discrepancy quick wins (small, do first)
12
+
13
+ - [x] Fix stale taproot comments claiming funding "cannot complete" (PR #32, merged).
14
+ README line 520 was already accurate (experimental because the feature bit
15
+ is staging upstream), so only the two source comments changed.
16
+ - [x] Resolve the `/channel/update-fee` naming trap (PR #33, merged): renamed to
17
+ `/channel/update-commitment-feerate` with the old path kept as a deprecated
18
+ alias; OpenAPI, docstrings and README clarified. Routing policy control
19
+ itself is M3.
20
+ - [x] DECIDED (Corey): advertise dual-fund (28) and zero-conf (50) by default
21
+ (PR #35, merged). Includes a trusted-peer gate rejecting a zero_conf
22
+ channel_type from untrusted peers on both v1 and v2 open paths.
23
+ - [x] Sweep other defined-but-never-advertised bits for intent (PR #32, merged): each of
24
+ LARGE_CHANNELS(18), ANCHOR_OUTPUTS(20), GOSSIP_QUERIES_EX(10),
25
+ UPFRONT_SHUTDOWN_SCRIPT(4), OPTION_WILL_FUND(112), ROUTE_BLINDING(24),
26
+ OPTION_TAPROOT(180/181) now documented in defaultFeatures(). Wumbo wiring
27
+ itself is an M3 item.
28
+ - [x] Legacy v1 `open_channel` path did not validate chain_hash (the v2 path
29
+ already did). Same guard added to `handleOpenChannel` + test (PR #34, merged).
30
+ - [x] `decodeInvoiceRequestTlv` returned a zero-buffer offerId placeholder;
31
+ now computed from the mirrored offer TLV records, and
32
+ `handleInvoiceRequest` reuses the decoded value + tests (PR #34, merged).
33
+
34
+ ## M1. Recovery and backup (highest fund-safety impact)
35
+
36
+ - [x] Static channel backup (SCB) equivalent (PR #38, merged): portable, versioned,
37
+ encrypted per-channel backup blob (peer pubkey, funding outpoint,
38
+ basepoints/channel key index) that is sufficient to trigger the
39
+ data-loss-protect recovery path. Export via library + daemon endpoint + CLI;
40
+ auto-refresh on every channel open/close.
41
+ - [x] "We fell behind" recovery flow (PR #36, merged): reestablish proof marks the
42
+ channel dataLossDetected + ERRORED (persist-first), sends a BOLT 1 error,
43
+ refuses all local broadcasts (forceClose + stuck-channel timer), and sweeps
44
+ only to_remote from the peer's THEIR_FUTURE_COMMITMENT via the chain monitor.
45
+ - [x] Taproot to_remote sweep in SCB recovery (PR #63, merged): the taproot output
46
+ resolver bailed without remote basepoints or a per-commitment point, so a
47
+ restored simple-taproot channel tracked its to_remote but never swept it.
48
+ The taproot to_remote leaf pays our STATIC payment basepoint (like the
49
+ static_remotekey and anchor variants), so it now resolves with zero peer
50
+ key material; the full taproot key set is derived only for HTLC leaves.
51
+ No SCB format change needed (v1 entries already carry channelKeyIndex +
52
+ channelType). Proven live on regtest: open, SCB export, wipe, peer
53
+ MuSig2 force-close, restore, sweep confirms after the 1-block CSV.
54
+ - [x] Restore API (PR #39, merged): daemon endpoint + CLI command that ingests a DB
55
+ backup or SCB blob and starts recovery (previously restore was manual file
56
+ placement; `POST /backup` had no counterpart).
57
+ - [x] Encryption at rest for the node SQLite DB (PR #37, merged): AES-256-GCM
58
+ envelope encryption of sensitive tables (htlc_shared_secrets included) keyed
59
+ via HKDF from the seed, default-on in BeignetNode with in-place migration and
60
+ an opt-out flag.
61
+ - [x] Onchain wallet (PR #41, merged): documented that persistence encryption is
62
+ delegated to the host TStorage, plus an optional built-in encryption wrapper
63
+ (`createEncryptedStorage`, AES-256-GCM keyed via HKDF from the seed, lazy
64
+ plaintext migration). Daemon audit: BeignetNode passes no wallet storage at
65
+ all; persistence item added under M4.
66
+ - [x] DECIDED (Corey): Peer storage (PR #42, merged): option_provide_storage bit 42
67
+ advertised, peer_storage (7) / peer_storage_retrieval (9) messages, server
68
+ stores one encrypted blob per channel/trusted peer (rate-limited, returned on
69
+ every reconnect), client pushes our seed-encrypted SCB to capable peers on
70
+ each refresh and keeps the newest valid retrieved copy; recovery stays
71
+ explicit via POST /restore/scb. No auto-restore.
72
+
73
+ ## M2. Watchtower
74
+
75
+ - [x] Watchtower client (PR #48, merged): LND altruist wtwire protocol (public-tower
76
+ interop), XChaCha20-Poly1305 v0 justice blobs shipped at every revocation,
77
+ per-session Noise keys, persisted sessions + un-acked backlog with retry,
78
+ config watchtowers[] URIs. Deferred + documented: anchor to_remote and
79
+ taproot (v1 blob) coverage, reward sessions.
80
+ - [~] Anchor + taproot tower coverage (this PR): LND v1 (taproot) justice kits
81
+ (300-byte plaintext pinned byte-exact to LND justice_kit_packet.go, same
82
+ XChaCha20 envelope), tower-side reconstruction cross-checked against a
83
+ REAL revoked taproot commitment. FIXES a fund-safety gap: anchor blobs
84
+ previously shipped under the legacy session type with the anchor
85
+ to_local weight, so an LND tower's reconstructed sweep value differed
86
+ and the signature could never verify (anchor breaches unpunishable);
87
+ anchor backups now negotiate blob-type-6 sessions and pack the P2WSH
88
+ 1-CSV to_remote. Per-blob-type session slots per tower (own session
89
+ keys, graceful REJECT_BLOB_TYPE queueing, MAX_UPDATES rotation), schema
90
+ v9 (blob_type on updates, session-key dialing flag). Live vs LND v0.20:
91
+ 6/6 including anchor and taproot sessions acked (LND v0.20 accepts blob
92
+ type 10). Reward sessions remain out of scope.
93
+ - [x] Live LND tower interop (PR #62, merged): session negotiation, real
94
+ revoked-commitment backups acked with advancing sequence numbers, and
95
+ per-identity sessions validated against a real LND v0.20 altruist tower
96
+ (docker lnd now runs --watchtower.active on 9911;
97
+ tests/lightning/interop/watchtower-lnd.test.ts). Found and fixed a live
98
+ bug: the wtwire regtest chain_hash constant was stored in display byte
99
+ order, so a real regtest LND tower rejected Init with "unknown chain
100
+ hash" (mainnet/testnet/signet were correct); CI regression tests pin all
101
+ chain hashes to the interop-proven channel-layer constants.
102
+ - [?] Watchtower server mode (lower priority; decide whether beignet should offer it).
103
+ - [x] Document the single-process online-requirement (PR #48, merged: README limitations
104
+ table updated alongside the tower client).
105
+
106
+ ## M3. Routing-node operations
107
+
108
+ - [x] Routing fee-policy control (PR #40, merged): set base_fee_msat, fee_proportional_millionths,
109
+ cltv_expiry_delta, htlc_minimum/maximum_msat per channel (and a node-wide
110
+ default), regenerating channel_update. Library method + daemon
111
+ `/channel/update-policy` + CLI. Internal pieces exist privately
112
+ (`refreshChannelUpdate`, `maybeAdoptPeerChannelPolicy` in lightning-node.ts).
113
+ - [x] Forwarding history and fee accounting (PR #43, merged): persist settled forwards
114
+ with amounts, fees earned, timestamps, channel pair; `listforwards`-style API via
115
+ library + daemon `/forwards` + CLI.
116
+ - [x] Graph query surface (PR #44, merged): describegraph, getnodeinfo(pubkey),
117
+ getchaninfo(scid), queryroutes via daemon `/graph/info`, `/graph/node`,
118
+ `/graph/channel`, `/graph/describe` (paged), `/route/query` + CLI
119
+ `graph`/`route query` commands (library `getGraph()` already existed).
120
+ - [x] Expose `sendPaymentToRoute` (PR #44, merged): daemon
121
+ `/payment/send-to-route` + CLI `payment send-to-route`, composing with
122
+ `/route/query` output.
123
+ - [x] option_wumbo (PR #45, merged): largeChannels config flag advertises LARGE_CHANNELS and
124
+ lifts the 2^24 sat cap (10 BTC absolute ceiling) at every enforcement site incl.
125
+ v1/v2 opens and three new splice capacity checks; acceptor gated on flag AND
126
+ the peer's advertised bit.
127
+ - [x] Connect by node id alone (PR #45, merged): connectPeer(pubkey) resolves addresses from
128
+ gossip node_announcement in announced order (Tor skipped without socks5Proxy,
129
+ .onion re-encoded for dialing), DNS bootstrap fallback, error lists every attempt.
130
+ - [~] Advisor execution, phase 1 (this PR): rebalanceChannel (first-hop-pinned route,
131
+ final hop via our own invoice hint, strict maxFeeSats abort BEFORE sending,
132
+ HTLC-cap clamping) + executeRebalanceRecommendations with a persisted UTC-day
133
+ fee budget; off by default.
134
+ - [~] Advisor execution, phase 2 (this PR): autoTuneFees loop nudging per-channel ppm
135
+ +/-25% (floor/ceil clamped, one adjustment per channel per interval) from
136
+ depletion + the #43 forwarding ledger via the #40 policy API; off by default.
137
+ - [x] Fee estimator sanity clamp (PR #45, merged): estimateFee output clamped to 5000 sat/vB
138
+ (floor 1) at all five consumer sites with a structured warning when adjusted;
139
+ sweep MAX_FEE_BUMP_MULTIPLIER untouched.
140
+
141
+ ## M4. Daemon / CLI surface gaps (library has it, surface does not)
142
+
143
+ - [x] Hold invoices end to end (PR #47, merged): createHoldInvoice (caller-supplied hash),
144
+ settleHoldInvoice, cancelHoldInvoice (works pre-accept, restart-safe),
145
+ listHoldInvoices; CLTV auto-cancel respected and the near-expiry claim
146
+ backstop no longer force-closes on parked holds with unrevealed preimages.
147
+ - [x] Onchain power endpoints (PR #49, merged): POST /send-max, /tx/bump-fee, /tx/boost
148
+ (auto RBF-else-CPFP), GET /transactions/boostable, POST /consolidate
149
+ (send-max-to-self). Also fixes the daemon wallet never signalling BIP 125
150
+ (rbf was off, bump-fee was permanently dead).
151
+ - [x] Persist the daemon's onchain wallet state (PR #49, merged): TStorage adapter over the
152
+ encrypted SQLite (wallet_data table, schema v8, per-network scoped twice: db
153
+ file + key prefix); boots load from disk and refresh incrementally. Note:
154
+ dailySpendLimit remains LN-only by existing design; onchain routes mirror
155
+ /send (no accounting) - flagged for a future decision.
156
+ DECIDED + implemented (PR #54, merged): combined LN+onchain daily budget; external
157
+ onchain sends count amount+fee (send, send-max), consolidate/channel
158
+ funding/fee bumps excluded; /spend-limit gains a breakdown.
159
+ - [x] sign/verify message with the node key (PR #47, merged): LND-compatible construction
160
+ (prefix, double-SHA256, compact recoverable ECDSA, zbase32); live lncli
161
+ cross-check noted as an interop follow-up.
162
+ - [ ] Onchain message signing (BIP322 plus legacy fallback) in the wallet layer.
163
+ - [x] Expose existing methods with no route (PR #47, merged): syncGossip, syncRapidGossip,
164
+ getChannelDiagnostics, validateAddress, recoverFallbackFunds, triggerBackup
165
+ all routed + CLI.
166
+ - [~] CLI parity sweep (this PR): every one of the 114 daemon routes now has a CLI
167
+ command or a documented intentionally-none entry (/events SSE, /openapi.json,
168
+ deprecated /channel/update-fee alias); enforced by a source-derived
169
+ regression test that fails on future drift either way.
170
+ - [~] Event granularity (this PR): invoice:settled (never fires on keysend),
171
+ channel:opening / pending-close / force-closing (local and remote, deduped),
172
+ htlc:forwarded/fulfilled/failed behind an htlcEvents flag; all wired through
173
+ SSE + webhooks with wildcard coverage. invoice:expired skipped: no issued-
174
+ invoice expiry sweep exists (payer-side scan only); would be new machinery.
175
+ - [~] Seed generation parity (this PR): documented (README + OpenAPI): seed creation
176
+ is CLI init only; GET /mnemonic reveals it only when apiToken is configured.
177
+
178
+ ## M5. Onchain wallet features
179
+
180
+ - [x] Watch-only wallets (PR #51, merged): Wallet.createWatchOnly from any SLIP-132
181
+ xpub/ypub/zpub/tpub/upub/vpub, full read-only surface, byte-identical
182
+ derivation to the full wallet, every signing path guarded with a typed
183
+ WatchOnlySigningError. Library-only (the daemon always has the mnemonic).
184
+ - [x] External-signer PSBT flow (PR #51, merged): buildPsbt (unsigned, with witnessUtxo,
185
+ bip32Derivation fingerprint/path/pubkey, taproot fields, legacy
186
+ nonWitnessUtxo), importSignedPsbt (validates every signature before
187
+ finalizing, no broadcast), wallet.broadcastTransaction; daemon /psbt/build,
188
+ /psbt/import-signed, /psbt/combine + CLI psbt commands.
189
+ - [x] PSBT combine for multi-party signing (PR #51, merged): combinePsbts.
190
+ - [x] Multisig / P2WSH (PR #57, merged; re-land of PR #55 which merged with red CI
191
+ and was reverted in PR #56): Wallet.createMultisig, BIP 48 derivation,
192
+ wsh(sortedmulti()) with BIP 67 ordering, watch-only coordinator support,
193
+ spending exclusively via the PSBT flow with fail-closed threshold
194
+ enforcement, descriptor export with checksums. Library-only. Re-land fixed
195
+ the coin-select regression (applyMultisigInputWeights assumed a wallet is
196
+ always attached; autoCoinSelect must work without one) and pinned that
197
+ property with a regression test.
198
+ (Tor support for Electrum: DEFERRED by Corey 2026-07-10, moved to M7.)
199
+ - [x] Fee estimation privacy (PR #53, merged): feeEstimationSource 'auto' (default,
200
+ Electrum first) | 'electrum' (never HTTP) | 'http'; every remote rate
201
+ clamped to 5000 sat/vB.
202
+ - [x] Robust multi-server Electrum failover (PR #53, merged): deterministic ordered
203
+ rotation with per-server 60s cooldown, then network fallback peers (never
204
+ for regtest); lightning reconnect monitor untouched.
205
+ - [x] BIP21 URI generation (PR #53, merged): encodeBip21 + POST /address/new bip21
206
+ option + CLI address --bip21.
207
+ - [x] Public UTXO freeze/unfreeze API (PR #54, merged): freeze/unfreeze/listFrozen +
208
+ getBalanceBreakdown; ALSO fixes a live gap where the blacklist was only
209
+ applied when the caller passed no explicit UTXO list.
210
+ - [x] Per-address user labels (PR #54, merged): setAddressLabel/getAddressLabel/list +
211
+ daemon/CLI; the legacy IAddressData.label field is untouched.
212
+ - [x] Signet network support (PR #53, merged): full onchain + lightning (chain hash,
213
+ coin type 1, daemon --network signet, default signet Electrum peer).
214
+ - [x] Wallet birthday (PR #54, merged): validated, persisted, earliest-wins metadata
215
+ exposed in descriptors. Candid finding: the Electrum protocol has no
216
+ height-filtered scans, so nothing is boundable today; documented as
217
+ forward-looking for bitcoind/compact-filter backends.
218
+ - [x] Multi-account support (PR #54, merged): account option threaded through derivation
219
+ and storage keys (account 0 keeps the legacy format); library-only, daemon
220
+ stays single-account.
221
+ - [x] Descriptor export (PR #54, merged): all four script types with BIP 380 checksums
222
+ validated against Bitcoin Core vectors; watch-only supported, no private
223
+ key material ever emitted.
224
+ - [?] Silent payments (BIP352) receive/send. Larger effort; decide priority.
225
+ - [?] Payjoin (BIP78/BIP77). Decide priority.
226
+ - [?] Alternate chain backends (bitcoind RPC, Esplora). IChainBackend exists for
227
+ lightning; onchain wallet is Electrum-coupled. Decide priority.
228
+
229
+ ## M6. Security and auth hardening
230
+
231
+ - [x] Scoped API auth (PR #58, merged): multiple named API keys (apiKeys config) with
232
+ readonly/invoice/admin scopes alongside the legacy apiToken (implicit
233
+ admin); explicit route-to-scope map with a source-derived drift test,
234
+ unclassified routes fail closed to admin-only; SHA-256 +
235
+ crypto.timingSafeEqual comparison for named keys and the legacy token;
236
+ 401 vs 403 distinction; runtime revocation by name (POST /auth/keys/revoke)
237
+ plus durable removal via config.
238
+ - [x] Remote/external signer interface (PR #60, merged): ISigner + SignerFactory in
239
+ keys/signer.ts covering every channel-state-machine signature (funding
240
+ digest, commitment/closing ECDSA, MuSig2 partial, second-level HTLC with
241
+ per-commitment derivation INSIDE the signer, taproot Schnorr HTLC);
242
+ ChannelSigner stays the in-process default constructed from the raw key
243
+ Buffers; signerFactory injectable via INodeConfig/IChannelManagerConfig;
244
+ zero behavior change, byte-identity pinned against pre-refactor vectors.
245
+ Deliberately synchronous (documented): remote implementations orchestrate
246
+ above the state machine; sync-to-async conversion noted as a follow-up.
247
+ Note: ChainMonitor sweep/justice paths still consume raw basepoint
248
+ secrets directly (separate surface, future work).
249
+ - [?] mTLS / client certificates for the daemon. Decide priority.
250
+ - [?] Key rotation strategy. Decide scope.
251
+ - [x] Leveled logging (PR #61, merged): platform-neutral src/logger.ts (ILogger
252
+ debug/info/warn/error, createConsoleLogger with level filtering,
253
+ noopLogger), injectable via Wallet config, INodeConfig, and
254
+ BeignetNodeOptions; daemon --log-level flag / BEIGNET_LOG_LEVEL env /
255
+ logLevel config writing to stderr (stdout stays reserved for command
256
+ output, default silent); LightningNode mirrors structured-log entries to
257
+ logger.debug; the persisted SQLite action log is untouched; defaults
258
+ preserve pre-existing output at every call site.
259
+
260
+ ## M7. Deferred / decide-later protocol features
261
+
262
+ Explicitly parked. Revisit each quarter or on ecosystem demand.
263
+
264
+ - [ ] BOLT12 refunds and recurrence
265
+ - [ ] Attributable failures (attribution_data)
266
+ - [ ] Trampoline routing
267
+ - [ ] AMP
268
+ - [ ] LSPS0/1/2 (client side first if Blocktank integration wants it)
269
+ - [ ] Dynamic commitments
270
+ - [ ] PTLCs
271
+ - [ ] WebSocket transport (relevant to the browser port)
272
+ - [ ] Tor hidden-service inbound provisioning (external today, document setup)
273
+ - [ ] Legacy option_anchor_outputs bit 20 (likely never; modern bit 22 shipped)
274
+ - [ ] Tor support for Electrum (deferred 2026-07-10): route TCP/SSL through a SOCKS5
275
+ proxy like the lightning transport already does.
276
+
277
+ ---
278
+
279
+ ## Suggested session order
280
+
281
+ 1. M0 (one small PR, immediate wins)
282
+ 2. M1 (SCB + fell-behind recovery + restore + DB encryption)
283
+ 3. M3 fee-policy control + forwarding history (unblocks routing-node use)
284
+ 4. M4 hold invoices + onchain power endpoints + sign/verifymessage
285
+ 5. M2 watchtower client
286
+ 6. M5 watch-only + external signer PSBT flow, then remaining M5 items
287
+ 7. M6, then re-triage M7
288
+
289
+ ## Session log
290
+
291
+ - 2026-07-09: Roadmap created from the four-domain feature review. No code changes yet.
292
+ - 2026-07-09 (same session): M0 executed as three PRs awaiting review: #32 (roadmap +
293
+ taproot comment corrections + feature-bit gating docs), #33 (update-fee endpoint
294
+ rename with deprecated alias), #34 (v1 open_channel chain_hash validation +
295
+ invoice_request offerId computation). Open decision for Corey: default advertising
296
+ of dual_fund/zero_conf, see the [?] item above.
297
+ - 2026-07-09 (later): M0 PRs #32-#34 merged; decision made to advertise dual_fund +
298
+ zero_conf by default, landed as PR #35 (merged, includes untrusted-peer zero_conf
299
+ channel_type rejection). M1 started: PR #36 open (fell-behind DLP recovery, suite
300
+ 3094/0); storage encryption at rest in progress in a parallel worktree.
301
+ - 2026-07-09 (cont.): M1 core merged as #36-#39 (DLP fell-behind recovery, storage
302
+ encryption, SCB export, restore API). M3 started: routing fee-policy control.
303
+ - 2026-07-09 (cont.): PR #40 merged. M1 closers queued: wallet storage encryption
304
+ wrapper + peer storage (option_provide_storage).
305
+ - 2026-07-09 (cont.): PR #42 merged, M1 fully closed. M3 resumed: forwarding history.
306
+ - 2026-07-10: PR #63 merged (taproot SCB-recovery sweep). Anchor + taproot
307
+ tower coverage (this PR) closes the last queued interop follow-up and fixes
308
+ the anchor-blob session-type fund-safety gap; only [?] decision items remain
309
+ on the roadmap (mTLS, key rotation, silent payments, payjoin, alternate
310
+ chain backends, watchtower server mode).
311
+ - 2026-07-10: PR #62 merged (regtest wtwire chain-hash fix + live LND tower
312
+ interop). Taproot SCB-recovery sweep (PR #63) closes the M1 known
313
+ limitation; watchtower v1 taproot blobs in progress in a parallel worktree.
314
+ - 2026-07-10: PR #61 merged (leveled logging), closing the buildable M6 items.
315
+ Interop follow-ups (this PR): lncli verifymessage cross-check passed live in
316
+ both directions vs LND v0.20 (beignet signature recovers our exact pubkey
317
+ via lncli verifymessage; LND signature verifies in beignet and recovers
318
+ LND's identity key; no code change needed). Live LND tower interop test
319
+ added, which caught and fixed the regtest wtwire chain_hash byte-order bug.
320
+ - 2026-07-10: PR #60 merged (ISigner abstraction). Leveled logging (PR #61)
321
+ closes the buildable M6 items; remaining M6 entries are the mTLS and key
322
+ rotation [?] decisions.
323
+ - 2026-07-10: PR #58 merged (scoped API auth) and v0.3.0 released (PR #59,
324
+ tag v0.3.0 at the multisig re-land point for npm publish). ISigner
325
+ remote-signer abstraction (PR #60) is M6 item 2 of 3; leveled logging
326
+ follows.
327
+ - 2026-07-10: PR #57 merged (multisig P2WSH re-land). M6 started with three
328
+ parallel branches: scoped API auth (PR #58), ISigner remote-signer
329
+ abstraction, and leveled logging.
330
+ - 2026-07-10: multisig P2WSH re-landed (PR #57). PR #55 had merged with a red
331
+ unit-test job through a merge-gate hole and was reverted in PR #56: its
332
+ applyMultisigInputWeights helper dereferenced the wallet unconditionally,
333
+ breaking autoCoinSelect on wallet-less Transaction instances (the six
334
+ deterministic coin-select tests). Re-land tolerates a missing wallet, adds a
335
+ regression test pinning wallet-less autoCoinSelect, and the merge gate is now
336
+ strict (>= 3 check lines, all pass, empty output blocks).
337
+ - 2026-07-10: PR #54 merged (batch C). Multisig P2WSH (this PR) completes the
338
+ active M5 items; also repairs README merge markers PR #54 shipped.
339
+ - 2026-07-10: PR #53 merged (Electrum layer). Batch C (this PR): combined spend
340
+ limit per Corey, UTXO freeze (+ selection-gap fix), labels, birthday,
341
+ multi-account, descriptor export. Multisig P2WSH next as its own PR.
342
+ - 2026-07-10: PR #51 merged (watch-only + PSBT flow; CI now isolates the offline
343
+ suites from live-Electrum tests). PR #52 merged (untracked a node_modules symlink
344
+ #51 accidentally committed; .gitignore pattern hardened). Batch B (this PR):
345
+ Electrum fee source, failover, signet, BIP21 encode.
346
+ - 2026-07-10: PRs #49/#50 completed M4. M5 started; Tor-for-Electrum deferred to M7
347
+ (Corey). DECIDED: dailySpendLimit becomes a combined LN+onchain budget (external
348
+ sends count; consolidate/channel-funding/fee-bumps excluded) - lands in batch C.
349
+ Batch A (this PR): watch-only wallets + external-signer PSBT flow.
350
+ - 2026-07-09 (cont.): PR #49 merged (batch 2a). Batch 2b (this PR): CLI parity
351
+ sweep + event granularity + seed-gen note; completes M4.
352
+ - 2026-07-09 (cont.): PR #48 merged (watchtower client, M2 core). M4 batch 2a
353
+ (this PR): onchain power endpoints + daemon wallet persistence.
354
+ - 2026-07-09 (cont.): PR #47 merged (M4 batch 1). Watchtower client (this PR)
355
+ lands the M2 core.
356
+ - 2026-07-09 (cont.): PR #46 merged, M3 complete. M2 watchtower client prioritized
357
+ (in progress, parallel) per Corey; M4 batch 1 (this PR): hold invoices,
358
+ sign/verifymessage, unrouted-method exposure.
359
+ - 2026-07-09 (cont.): PR #45 merged (wumbo, connect-by-id, fee clamp). Advisor
360
+ execution (this PR) completes M3.
361
+ - 2026-07-09 (cont.): PR #44 merged (graph queries + send-to-route). M3 small items
362
+ (wumbo, connect-by-id, fee clamp) this PR; advisor execution lands next.
363
+ - 2026-07-09 (cont.): forwarding history merged as PR #43. M3 continued: graph query
364
+ surface (graph info/node/channel/describe + route query) and sendPaymentToRoute
365
+ exposure, one branch/PR for both since send-to-route consumes route-query output.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beignet",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "A self-custodial, JS Bitcoin wallet + Lightning Network management library.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {