beignet 0.2.0 → 0.3.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 (195) hide show
  1. package/README.md +284 -1
  2. package/dist/cli/beignet-node.js +1019 -47
  3. package/dist/cli/beignet-node.js.map +1 -1
  4. package/dist/cli/cli.js +1201 -16
  5. package/dist/cli/cli.js.map +1 -1
  6. package/dist/cli/config.js +21 -1
  7. package/dist/cli/config.js.map +1 -1
  8. package/dist/cli/daemon.js +342 -16
  9. package/dist/cli/daemon.js.map +1 -1
  10. package/dist/cli/errors.js +2 -0
  11. package/dist/cli/errors.js.map +1 -1
  12. package/dist/cli/openapi.js +1207 -14
  13. package/dist/cli/openapi.js.map +1 -1
  14. package/dist/cli/restore.js +89 -0
  15. package/dist/cli/restore.js.map +1 -0
  16. package/dist/cli/wallet-storage.js +34 -0
  17. package/dist/cli/wallet-storage.js.map +1 -0
  18. package/dist/electrum/index.js +105 -10
  19. package/dist/electrum/index.js.map +1 -1
  20. package/dist/lightning/advisor/fee-tuner.js +42 -0
  21. package/dist/lightning/advisor/fee-tuner.js.map +1 -0
  22. package/dist/lightning/advisor/index.js +9 -1
  23. package/dist/lightning/advisor/index.js.map +1 -1
  24. package/dist/lightning/advisor/rebalance-planner.js +55 -0
  25. package/dist/lightning/advisor/rebalance-planner.js.map +1 -0
  26. package/dist/lightning/backup/index.js +18 -0
  27. package/dist/lightning/backup/index.js.map +1 -0
  28. package/dist/lightning/backup/scb.js +42 -0
  29. package/dist/lightning/backup/scb.js.map +1 -0
  30. package/dist/lightning/chain/chain-monitor.js +27 -0
  31. package/dist/lightning/chain/chain-monitor.js.map +1 -1
  32. package/dist/lightning/chain/output-resolver.js +55 -6
  33. package/dist/lightning/chain/output-resolver.js.map +1 -1
  34. package/dist/lightning/chain/types.js +1 -0
  35. package/dist/lightning/chain/types.js.map +1 -1
  36. package/dist/lightning/channel/channel-manager.js +64 -0
  37. package/dist/lightning/channel/channel-manager.js.map +1 -1
  38. package/dist/lightning/channel/channel-state.js.map +1 -1
  39. package/dist/lightning/channel/channel.js +124 -4
  40. package/dist/lightning/channel/channel.js.map +1 -1
  41. package/dist/lightning/channel/dual-funding.js +6 -5
  42. package/dist/lightning/channel/dual-funding.js.map +1 -1
  43. package/dist/lightning/channel/types.js +3 -1
  44. package/dist/lightning/channel/types.js.map +1 -1
  45. package/dist/lightning/channel/validation.js +3 -3
  46. package/dist/lightning/channel/validation.js.map +1 -1
  47. package/dist/lightning/crypto/index.js +1 -0
  48. package/dist/lightning/crypto/index.js.map +1 -1
  49. package/dist/lightning/crypto/message-signing.js +116 -0
  50. package/dist/lightning/crypto/message-signing.js.map +1 -0
  51. package/dist/lightning/crypto/xchacha20poly1305.js +77 -0
  52. package/dist/lightning/crypto/xchacha20poly1305.js.map +1 -0
  53. package/dist/lightning/features/flags.js +1 -0
  54. package/dist/lightning/features/flags.js.map +1 -1
  55. package/dist/lightning/gossip/messages.js +37 -1
  56. package/dist/lightning/gossip/messages.js.map +1 -1
  57. package/dist/lightning/index.js +2 -1
  58. package/dist/lightning/index.js.map +1 -1
  59. package/dist/lightning/keys/wallet-keys.js +1 -0
  60. package/dist/lightning/keys/wallet-keys.js.map +1 -1
  61. package/dist/lightning/message/index.js +1 -0
  62. package/dist/lightning/message/index.js.map +1 -1
  63. package/dist/lightning/message/peer-storage.js +43 -0
  64. package/dist/lightning/message/peer-storage.js.map +1 -0
  65. package/dist/lightning/message/types.js +2 -0
  66. package/dist/lightning/message/types.js.map +1 -1
  67. package/dist/lightning/node/lightning-node.js +1583 -235
  68. package/dist/lightning/node/lightning-node.js.map +1 -1
  69. package/dist/lightning/node/types.js +18 -1
  70. package/dist/lightning/node/types.js.map +1 -1
  71. package/dist/lightning/offer/offer-manager.js +2 -5
  72. package/dist/lightning/offer/offer-manager.js.map +1 -1
  73. package/dist/lightning/offer/tlv.js +3 -1
  74. package/dist/lightning/offer/tlv.js.map +1 -1
  75. package/dist/lightning/storage/encryption.js +67 -0
  76. package/dist/lightning/storage/encryption.js.map +1 -0
  77. package/dist/lightning/storage/index.js +1 -0
  78. package/dist/lightning/storage/index.js.map +1 -1
  79. package/dist/lightning/storage/serialization.js +6 -2
  80. package/dist/lightning/storage/serialization.js.map +1 -1
  81. package/dist/lightning/storage/sqlite-storage.js +387 -33
  82. package/dist/lightning/storage/sqlite-storage.js.map +1 -1
  83. package/dist/lightning/watchtower/blob.js +135 -0
  84. package/dist/lightning/watchtower/blob.js.map +1 -0
  85. package/dist/lightning/watchtower/index.js +55 -0
  86. package/dist/lightning/watchtower/index.js.map +1 -0
  87. package/dist/lightning/watchtower/justice.js +182 -0
  88. package/dist/lightning/watchtower/justice.js.map +1 -0
  89. package/dist/lightning/watchtower/tower-connection.js +208 -0
  90. package/dist/lightning/watchtower/tower-connection.js.map +1 -0
  91. package/dist/lightning/watchtower/types.js +3 -0
  92. package/dist/lightning/watchtower/types.js.map +1 -0
  93. package/dist/lightning/watchtower/watchtower-client.js +402 -0
  94. package/dist/lightning/watchtower/watchtower-client.js.map +1 -0
  95. package/dist/lightning/watchtower/wtwire.js +201 -0
  96. package/dist/lightning/watchtower/wtwire.js.map +1 -0
  97. package/dist/shapes/electrum.js +32 -1
  98. package/dist/shapes/electrum.js.map +1 -1
  99. package/dist/shapes/wallet.js +11 -1
  100. package/dist/shapes/wallet.js.map +1 -1
  101. package/dist/transaction/index.js +163 -15
  102. package/dist/transaction/index.js.map +1 -1
  103. package/dist/types/cli/beignet-node.d.ts +144 -3
  104. package/dist/types/cli/daemon.d.ts +2 -0
  105. package/dist/types/cli/errors.d.ts +2 -0
  106. package/dist/types/cli/restore.d.ts +10 -0
  107. package/dist/types/cli/types.d.ts +228 -1
  108. package/dist/types/cli/wallet-storage.d.ts +3 -0
  109. package/dist/types/electrum/index.d.ts +12 -0
  110. package/dist/types/electrum.js +1 -0
  111. package/dist/types/electrum.js.map +1 -1
  112. package/dist/types/lightning/advisor/fee-tuner.d.ts +20 -0
  113. package/dist/types/lightning/advisor/index.d.ts +4 -0
  114. package/dist/types/lightning/advisor/rebalance-planner.d.ts +12 -0
  115. package/dist/types/lightning/backup/index.d.ts +1 -0
  116. package/dist/types/lightning/backup/scb.d.ts +24 -0
  117. package/dist/types/lightning/chain/chain-monitor.d.ts +1 -0
  118. package/dist/types/lightning/chain/types.d.ts +1 -0
  119. package/dist/types/lightning/channel/channel-manager.d.ts +7 -0
  120. package/dist/types/lightning/channel/channel-state.d.ts +2 -0
  121. package/dist/types/lightning/channel/channel.d.ts +6 -0
  122. package/dist/types/lightning/channel/dual-funding.d.ts +2 -1
  123. package/dist/types/lightning/channel/types.d.ts +2 -0
  124. package/dist/types/lightning/channel/validation.d.ts +1 -1
  125. package/dist/types/lightning/crypto/index.d.ts +1 -0
  126. package/dist/types/lightning/crypto/message-signing.d.ts +9 -0
  127. package/dist/types/lightning/crypto/xchacha20poly1305.d.ts +3 -0
  128. package/dist/types/lightning/features/flags.d.ts +1 -0
  129. package/dist/types/lightning/gossip/messages.d.ts +4 -0
  130. package/dist/types/lightning/index.d.ts +1 -0
  131. package/dist/types/lightning/keys/wallet-keys.d.ts +2 -1
  132. package/dist/types/lightning/message/index.d.ts +1 -0
  133. package/dist/types/lightning/message/peer-storage.d.ts +9 -0
  134. package/dist/types/lightning/message/types.d.ts +2 -0
  135. package/dist/types/lightning/node/lightning-node.d.ts +116 -4
  136. package/dist/types/lightning/node/types.d.ts +62 -1
  137. package/dist/types/lightning/storage/encryption.d.ts +11 -0
  138. package/dist/types/lightning/storage/index.d.ts +1 -0
  139. package/dist/types/lightning/storage/serialization.d.ts +2 -0
  140. package/dist/types/lightning/storage/sqlite-storage.d.ts +43 -3
  141. package/dist/types/lightning/storage/types.d.ts +62 -0
  142. package/dist/types/lightning/watchtower/blob.d.ts +32 -0
  143. package/dist/types/lightning/watchtower/index.d.ts +9 -0
  144. package/dist/types/lightning/watchtower/justice.d.ts +29 -0
  145. package/dist/types/lightning/watchtower/tower-connection.d.ts +34 -0
  146. package/dist/types/lightning/watchtower/types.d.ts +44 -0
  147. package/dist/types/lightning/watchtower/watchtower-client.d.ts +67 -0
  148. package/dist/types/lightning/watchtower/wtwire.d.ts +90 -0
  149. package/dist/types/shapes/electrum.d.ts +3 -1
  150. package/dist/types/transaction/index.d.ts +6 -0
  151. package/dist/types/transaction.js.map +1 -1
  152. package/dist/types/types/electrum.d.ts +3 -2
  153. package/dist/types/types/transaction.d.ts +1 -1
  154. package/dist/types/types/wallet.d.ts +78 -4
  155. package/dist/types/utils/descriptors.d.ts +2 -0
  156. package/dist/types/utils/fees.d.ts +3 -0
  157. package/dist/types/utils/helpers.d.ts +3 -1
  158. package/dist/types/utils/index.d.ts +5 -0
  159. package/dist/types/utils/multisig.d.ts +29 -0
  160. package/dist/types/utils/transaction.d.ts +7 -0
  161. package/dist/types/utils/wallet-storage-encryption.d.ts +3 -0
  162. package/dist/types/utils/wallet.d.ts +1 -1
  163. package/dist/types/utils/watch-only.d.ts +12 -0
  164. package/dist/types/wallet/constants.d.ts +1 -0
  165. package/dist/types/wallet/index.d.ts +61 -4
  166. package/dist/types/wallet.js +3 -0
  167. package/dist/types/wallet.js.map +1 -1
  168. package/dist/utils/derivation-path.js +8 -7
  169. package/dist/utils/derivation-path.js.map +1 -1
  170. package/dist/utils/descriptors.js +56 -0
  171. package/dist/utils/descriptors.js.map +1 -0
  172. package/dist/utils/electrum.js +10 -2
  173. package/dist/utils/electrum.js.map +1 -1
  174. package/dist/utils/fees.js +19 -0
  175. package/dist/utils/fees.js.map +1 -0
  176. package/dist/utils/helpers.js +22 -5
  177. package/dist/utils/helpers.js.map +1 -1
  178. package/dist/utils/index.js +5 -0
  179. package/dist/utils/index.js.map +1 -1
  180. package/dist/utils/multisig.js +90 -0
  181. package/dist/utils/multisig.js.map +1 -0
  182. package/dist/utils/transaction.js +30 -3
  183. package/dist/utils/transaction.js.map +1 -1
  184. package/dist/utils/wallet-storage-encryption.js +45 -0
  185. package/dist/utils/wallet-storage-encryption.js.map +1 -0
  186. package/dist/utils/wallet.js +3 -1
  187. package/dist/utils/wallet.js.map +1 -1
  188. package/dist/utils/watch-only.js +102 -0
  189. package/dist/utils/watch-only.js.map +1 -0
  190. package/dist/wallet/constants.js +2 -1
  191. package/dist/wallet/constants.js.map +1 -1
  192. package/dist/wallet/index.js +787 -30
  193. package/dist/wallet/index.js.map +1 -1
  194. package/docs/ROADMAP.md +292 -0
  195. package/package.json +1 -1
@@ -0,0 +1,292 @@
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] Restore API (PR #39, merged): daemon endpoint + CLI command that ingests a DB
46
+ backup or SCB blob and starts recovery (previously restore was manual file
47
+ placement; `POST /backup` had no counterpart).
48
+ - [x] Encryption at rest for the node SQLite DB (PR #37, merged): AES-256-GCM
49
+ envelope encryption of sensitive tables (htlc_shared_secrets included) keyed
50
+ via HKDF from the seed, default-on in BeignetNode with in-place migration and
51
+ an opt-out flag.
52
+ - [x] Onchain wallet (PR #41, merged): documented that persistence encryption is
53
+ delegated to the host TStorage, plus an optional built-in encryption wrapper
54
+ (`createEncryptedStorage`, AES-256-GCM keyed via HKDF from the seed, lazy
55
+ plaintext migration). Daemon audit: BeignetNode passes no wallet storage at
56
+ all; persistence item added under M4.
57
+ - [x] DECIDED (Corey): Peer storage (PR #42, merged): option_provide_storage bit 42
58
+ advertised, peer_storage (7) / peer_storage_retrieval (9) messages, server
59
+ stores one encrypted blob per channel/trusted peer (rate-limited, returned on
60
+ every reconnect), client pushes our seed-encrypted SCB to capable peers on
61
+ each refresh and keeps the newest valid retrieved copy; recovery stays
62
+ explicit via POST /restore/scb. No auto-restore.
63
+
64
+ ## M2. Watchtower
65
+
66
+ - [x] Watchtower client (PR #48, merged): LND altruist wtwire protocol (public-tower
67
+ interop), XChaCha20-Poly1305 v0 justice blobs shipped at every revocation,
68
+ per-session Noise keys, persisted sessions + un-acked backlog with retry,
69
+ config watchtowers[] URIs. Deferred + documented: anchor to_remote and
70
+ taproot (v1 blob) coverage, reward sessions.
71
+ - [?] Watchtower server mode (lower priority; decide whether beignet should offer it).
72
+ - [x] Document the single-process online-requirement (PR #48, merged: README limitations
73
+ table updated alongside the tower client).
74
+
75
+ ## M3. Routing-node operations
76
+
77
+ - [x] Routing fee-policy control (PR #40, merged): set base_fee_msat, fee_proportional_millionths,
78
+ cltv_expiry_delta, htlc_minimum/maximum_msat per channel (and a node-wide
79
+ default), regenerating channel_update. Library method + daemon
80
+ `/channel/update-policy` + CLI. Internal pieces exist privately
81
+ (`refreshChannelUpdate`, `maybeAdoptPeerChannelPolicy` in lightning-node.ts).
82
+ - [x] Forwarding history and fee accounting (PR #43, merged): persist settled forwards
83
+ with amounts, fees earned, timestamps, channel pair; `listforwards`-style API via
84
+ library + daemon `/forwards` + CLI.
85
+ - [x] Graph query surface (PR #44, merged): describegraph, getnodeinfo(pubkey),
86
+ getchaninfo(scid), queryroutes via daemon `/graph/info`, `/graph/node`,
87
+ `/graph/channel`, `/graph/describe` (paged), `/route/query` + CLI
88
+ `graph`/`route query` commands (library `getGraph()` already existed).
89
+ - [x] Expose `sendPaymentToRoute` (PR #44, merged): daemon
90
+ `/payment/send-to-route` + CLI `payment send-to-route`, composing with
91
+ `/route/query` output.
92
+ - [x] option_wumbo (PR #45, merged): largeChannels config flag advertises LARGE_CHANNELS and
93
+ lifts the 2^24 sat cap (10 BTC absolute ceiling) at every enforcement site incl.
94
+ v1/v2 opens and three new splice capacity checks; acceptor gated on flag AND
95
+ the peer's advertised bit.
96
+ - [x] Connect by node id alone (PR #45, merged): connectPeer(pubkey) resolves addresses from
97
+ gossip node_announcement in announced order (Tor skipped without socks5Proxy,
98
+ .onion re-encoded for dialing), DNS bootstrap fallback, error lists every attempt.
99
+ - [~] Advisor execution, phase 1 (this PR): rebalanceChannel (first-hop-pinned route,
100
+ final hop via our own invoice hint, strict maxFeeSats abort BEFORE sending,
101
+ HTLC-cap clamping) + executeRebalanceRecommendations with a persisted UTC-day
102
+ fee budget; off by default.
103
+ - [~] Advisor execution, phase 2 (this PR): autoTuneFees loop nudging per-channel ppm
104
+ +/-25% (floor/ceil clamped, one adjustment per channel per interval) from
105
+ depletion + the #43 forwarding ledger via the #40 policy API; off by default.
106
+ - [x] Fee estimator sanity clamp (PR #45, merged): estimateFee output clamped to 5000 sat/vB
107
+ (floor 1) at all five consumer sites with a structured warning when adjusted;
108
+ sweep MAX_FEE_BUMP_MULTIPLIER untouched.
109
+
110
+ ## M4. Daemon / CLI surface gaps (library has it, surface does not)
111
+
112
+ - [x] Hold invoices end to end (PR #47, merged): createHoldInvoice (caller-supplied hash),
113
+ settleHoldInvoice, cancelHoldInvoice (works pre-accept, restart-safe),
114
+ listHoldInvoices; CLTV auto-cancel respected and the near-expiry claim
115
+ backstop no longer force-closes on parked holds with unrevealed preimages.
116
+ - [x] Onchain power endpoints (PR #49, merged): POST /send-max, /tx/bump-fee, /tx/boost
117
+ (auto RBF-else-CPFP), GET /transactions/boostable, POST /consolidate
118
+ (send-max-to-self). Also fixes the daemon wallet never signalling BIP 125
119
+ (rbf was off, bump-fee was permanently dead).
120
+ - [x] Persist the daemon's onchain wallet state (PR #49, merged): TStorage adapter over the
121
+ encrypted SQLite (wallet_data table, schema v8, per-network scoped twice: db
122
+ file + key prefix); boots load from disk and refresh incrementally. Note:
123
+ dailySpendLimit remains LN-only by existing design; onchain routes mirror
124
+ /send (no accounting) - flagged for a future decision.
125
+ DECIDED + implemented (PR #54, merged): combined LN+onchain daily budget; external
126
+ onchain sends count amount+fee (send, send-max), consolidate/channel
127
+ funding/fee bumps excluded; /spend-limit gains a breakdown.
128
+ - [x] sign/verify message with the node key (PR #47, merged): LND-compatible construction
129
+ (prefix, double-SHA256, compact recoverable ECDSA, zbase32); live lncli
130
+ cross-check noted as an interop follow-up.
131
+ - [ ] Onchain message signing (BIP322 plus legacy fallback) in the wallet layer.
132
+ - [x] Expose existing methods with no route (PR #47, merged): syncGossip, syncRapidGossip,
133
+ getChannelDiagnostics, validateAddress, recoverFallbackFunds, triggerBackup
134
+ all routed + CLI.
135
+ - [~] CLI parity sweep (this PR): every one of the 114 daemon routes now has a CLI
136
+ command or a documented intentionally-none entry (/events SSE, /openapi.json,
137
+ deprecated /channel/update-fee alias); enforced by a source-derived
138
+ regression test that fails on future drift either way.
139
+ - [~] Event granularity (this PR): invoice:settled (never fires on keysend),
140
+ channel:opening / pending-close / force-closing (local and remote, deduped),
141
+ htlc:forwarded/fulfilled/failed behind an htlcEvents flag; all wired through
142
+ SSE + webhooks with wildcard coverage. invoice:expired skipped: no issued-
143
+ invoice expiry sweep exists (payer-side scan only); would be new machinery.
144
+ - [~] Seed generation parity (this PR): documented (README + OpenAPI): seed creation
145
+ is CLI init only; GET /mnemonic reveals it only when apiToken is configured.
146
+
147
+ ## M5. Onchain wallet features
148
+
149
+ - [x] Watch-only wallets (PR #51, merged): Wallet.createWatchOnly from any SLIP-132
150
+ xpub/ypub/zpub/tpub/upub/vpub, full read-only surface, byte-identical
151
+ derivation to the full wallet, every signing path guarded with a typed
152
+ WatchOnlySigningError. Library-only (the daemon always has the mnemonic).
153
+ - [x] External-signer PSBT flow (PR #51, merged): buildPsbt (unsigned, with witnessUtxo,
154
+ bip32Derivation fingerprint/path/pubkey, taproot fields, legacy
155
+ nonWitnessUtxo), importSignedPsbt (validates every signature before
156
+ finalizing, no broadcast), wallet.broadcastTransaction; daemon /psbt/build,
157
+ /psbt/import-signed, /psbt/combine + CLI psbt commands.
158
+ - [x] PSBT combine for multi-party signing (PR #51, merged): combinePsbts.
159
+ - [~] Multisig / P2WSH (this PR, re-land of PR #55 which merged with red CI and
160
+ was reverted in PR #56): Wallet.createMultisig, BIP 48 derivation,
161
+ wsh(sortedmulti()) with BIP 67 ordering, watch-only coordinator support,
162
+ spending exclusively via the PSBT flow with fail-closed threshold
163
+ enforcement, descriptor export with checksums. Library-only. Re-land fixes
164
+ the coin-select regression (applyMultisigInputWeights assumed a wallet is
165
+ always attached; autoCoinSelect must work without one) and pins that
166
+ property with a regression test.
167
+ (Tor support for Electrum: DEFERRED by Corey 2026-07-10, moved to M7.)
168
+ - [x] Fee estimation privacy (PR #53, merged): feeEstimationSource 'auto' (default,
169
+ Electrum first) | 'electrum' (never HTTP) | 'http'; every remote rate
170
+ clamped to 5000 sat/vB.
171
+ - [x] Robust multi-server Electrum failover (PR #53, merged): deterministic ordered
172
+ rotation with per-server 60s cooldown, then network fallback peers (never
173
+ for regtest); lightning reconnect monitor untouched.
174
+ - [x] BIP21 URI generation (PR #53, merged): encodeBip21 + POST /address/new bip21
175
+ option + CLI address --bip21.
176
+ - [x] Public UTXO freeze/unfreeze API (PR #54, merged): freeze/unfreeze/listFrozen +
177
+ getBalanceBreakdown; ALSO fixes a live gap where the blacklist was only
178
+ applied when the caller passed no explicit UTXO list.
179
+ - [x] Per-address user labels (PR #54, merged): setAddressLabel/getAddressLabel/list +
180
+ daemon/CLI; the legacy IAddressData.label field is untouched.
181
+ - [x] Signet network support (PR #53, merged): full onchain + lightning (chain hash,
182
+ coin type 1, daemon --network signet, default signet Electrum peer).
183
+ - [x] Wallet birthday (PR #54, merged): validated, persisted, earliest-wins metadata
184
+ exposed in descriptors. Candid finding: the Electrum protocol has no
185
+ height-filtered scans, so nothing is boundable today; documented as
186
+ forward-looking for bitcoind/compact-filter backends.
187
+ - [x] Multi-account support (PR #54, merged): account option threaded through derivation
188
+ and storage keys (account 0 keeps the legacy format); library-only, daemon
189
+ stays single-account.
190
+ - [x] Descriptor export (PR #54, merged): all four script types with BIP 380 checksums
191
+ validated against Bitcoin Core vectors; watch-only supported, no private
192
+ key material ever emitted.
193
+ - [?] Silent payments (BIP352) receive/send. Larger effort; decide priority.
194
+ - [?] Payjoin (BIP78/BIP77). Decide priority.
195
+ - [?] Alternate chain backends (bitcoind RPC, Esplora). IChainBackend exists for
196
+ lightning; onchain wallet is Electrum-coupled. Decide priority.
197
+
198
+ ## M6. Security and auth hardening
199
+
200
+ - [ ] Scoped API auth: multiple named API keys with permission scopes (read-only,
201
+ invoice-only, admin) replacing the single static bearer token; constant-time
202
+ compare; key revocation.
203
+ - [ ] Remote/external signer interface for the node: abstract ChannelSigner behind an
204
+ ISigner so keys can live out of process (raw Buffers in INodeConfig today,
205
+ `node/types.ts:78-91`).
206
+ - [?] mTLS / client certificates for the daemon. Decide priority.
207
+ - [?] Key rotation strategy. Decide scope.
208
+ - [ ] Leveled logging (debug/info/warn/error) with injectable logger, alongside the
209
+ existing structured action log.
210
+
211
+ ## M7. Deferred / decide-later protocol features
212
+
213
+ Explicitly parked. Revisit each quarter or on ecosystem demand.
214
+
215
+ - [ ] BOLT12 refunds and recurrence
216
+ - [ ] Attributable failures (attribution_data)
217
+ - [ ] Trampoline routing
218
+ - [ ] AMP
219
+ - [ ] LSPS0/1/2 (client side first if Blocktank integration wants it)
220
+ - [ ] Dynamic commitments
221
+ - [ ] PTLCs
222
+ - [ ] WebSocket transport (relevant to the browser port)
223
+ - [ ] Tor hidden-service inbound provisioning (external today, document setup)
224
+ - [ ] Legacy option_anchor_outputs bit 20 (likely never; modern bit 22 shipped)
225
+ - [ ] Tor support for Electrum (deferred 2026-07-10): route TCP/SSL through a SOCKS5
226
+ proxy like the lightning transport already does.
227
+
228
+ ---
229
+
230
+ ## Suggested session order
231
+
232
+ 1. M0 (one small PR, immediate wins)
233
+ 2. M1 (SCB + fell-behind recovery + restore + DB encryption)
234
+ 3. M3 fee-policy control + forwarding history (unblocks routing-node use)
235
+ 4. M4 hold invoices + onchain power endpoints + sign/verifymessage
236
+ 5. M2 watchtower client
237
+ 6. M5 watch-only + external signer PSBT flow, then remaining M5 items
238
+ 7. M6, then re-triage M7
239
+
240
+ ## Session log
241
+
242
+ - 2026-07-09: Roadmap created from the four-domain feature review. No code changes yet.
243
+ - 2026-07-09 (same session): M0 executed as three PRs awaiting review: #32 (roadmap +
244
+ taproot comment corrections + feature-bit gating docs), #33 (update-fee endpoint
245
+ rename with deprecated alias), #34 (v1 open_channel chain_hash validation +
246
+ invoice_request offerId computation). Open decision for Corey: default advertising
247
+ of dual_fund/zero_conf, see the [?] item above.
248
+ - 2026-07-09 (later): M0 PRs #32-#34 merged; decision made to advertise dual_fund +
249
+ zero_conf by default, landed as PR #35 (merged, includes untrusted-peer zero_conf
250
+ channel_type rejection). M1 started: PR #36 open (fell-behind DLP recovery, suite
251
+ 3094/0); storage encryption at rest in progress in a parallel worktree.
252
+ - 2026-07-09 (cont.): M1 core merged as #36-#39 (DLP fell-behind recovery, storage
253
+ encryption, SCB export, restore API). M3 started: routing fee-policy control.
254
+ - 2026-07-09 (cont.): PR #40 merged. M1 closers queued: wallet storage encryption
255
+ wrapper + peer storage (option_provide_storage).
256
+ - 2026-07-09 (cont.): PR #42 merged, M1 fully closed. M3 resumed: forwarding history.
257
+ - 2026-07-10: multisig P2WSH re-landed (this PR). PR #55 had merged with a red
258
+ unit-test job through a merge-gate hole and was reverted in PR #56: its
259
+ applyMultisigInputWeights helper dereferenced the wallet unconditionally,
260
+ breaking autoCoinSelect on wallet-less Transaction instances (the six
261
+ deterministic coin-select tests). Re-land tolerates a missing wallet, adds a
262
+ regression test pinning wallet-less autoCoinSelect, and the merge gate is now
263
+ strict (>= 3 check lines, all pass, empty output blocks).
264
+ - 2026-07-10: PR #54 merged (batch C). Multisig P2WSH (this PR) completes the
265
+ active M5 items; also repairs README merge markers PR #54 shipped.
266
+ - 2026-07-10: PR #53 merged (Electrum layer). Batch C (this PR): combined spend
267
+ limit per Corey, UTXO freeze (+ selection-gap fix), labels, birthday,
268
+ multi-account, descriptor export. Multisig P2WSH next as its own PR.
269
+ - 2026-07-10: PR #51 merged (watch-only + PSBT flow; CI now isolates the offline
270
+ suites from live-Electrum tests). PR #52 merged (untracked a node_modules symlink
271
+ #51 accidentally committed; .gitignore pattern hardened). Batch B (this PR):
272
+ Electrum fee source, failover, signet, BIP21 encode.
273
+ - 2026-07-10: PRs #49/#50 completed M4. M5 started; Tor-for-Electrum deferred to M7
274
+ (Corey). DECIDED: dailySpendLimit becomes a combined LN+onchain budget (external
275
+ sends count; consolidate/channel-funding/fee-bumps excluded) - lands in batch C.
276
+ Batch A (this PR): watch-only wallets + external-signer PSBT flow.
277
+ - 2026-07-09 (cont.): PR #49 merged (batch 2a). Batch 2b (this PR): CLI parity
278
+ sweep + event granularity + seed-gen note; completes M4.
279
+ - 2026-07-09 (cont.): PR #48 merged (watchtower client, M2 core). M4 batch 2a
280
+ (this PR): onchain power endpoints + daemon wallet persistence.
281
+ - 2026-07-09 (cont.): PR #47 merged (M4 batch 1). Watchtower client (this PR)
282
+ lands the M2 core.
283
+ - 2026-07-09 (cont.): PR #46 merged, M3 complete. M2 watchtower client prioritized
284
+ (in progress, parallel) per Corey; M4 batch 1 (this PR): hold invoices,
285
+ sign/verifymessage, unrouted-method exposure.
286
+ - 2026-07-09 (cont.): PR #45 merged (wumbo, connect-by-id, fee clamp). Advisor
287
+ execution (this PR) completes M3.
288
+ - 2026-07-09 (cont.): PR #44 merged (graph queries + send-to-route). M3 small items
289
+ (wumbo, connect-by-id, fee clamp) this PR; advisor execution lands next.
290
+ - 2026-07-09 (cont.): forwarding history merged as PR #43. M3 continued: graph query
291
+ surface (graph info/node/channel/describe + route query) and sendPaymentToRoute
292
+ 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.3.0",
4
4
  "description": "A self-custodial, JS Bitcoin wallet + Lightning Network management library.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {