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
@@ -6,22 +6,42 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.SqliteStorage = void 0;
7
7
  const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
8
8
  const serialization_1 = require("./serialization");
9
+ const encryption_1 = require("./encryption");
9
10
  class SqliteStorage {
10
- constructor(dbPath, onCorruptRow) {
11
+ constructor(dbPath, onCorruptRow, opts) {
12
+ this.forwardingEventsMaxRows = 100000;
11
13
  this.db = new better_sqlite3_1.default(dbPath);
12
14
  this.onCorruptRow = onCorruptRow;
15
+ this.encryptionKey = opts?.encryptionKey;
13
16
  }
14
17
  reportCorruptRow(error) {
18
+ if (error instanceof encryption_1.StorageEncryptedError) {
19
+ throw error;
20
+ }
15
21
  if (this.onCorruptRow) {
16
22
  this.onCorruptRow(error);
17
23
  }
18
24
  }
25
+ _enc(value) {
26
+ return this.encryptionKey ? (0, encryption_1.encryptValue)(this.encryptionKey, value) : value;
27
+ }
28
+ _dec(value) {
29
+ if (!(0, encryption_1.isEncryptedValue)(value))
30
+ return value;
31
+ if (!this.encryptionKey) {
32
+ throw new encryption_1.StorageEncryptedError();
33
+ }
34
+ return (0, encryption_1.decryptValue)(this.encryptionKey, value);
35
+ }
19
36
  open(opts) {
20
37
  this.db.pragma('journal_mode = WAL');
21
38
  this.db.pragma(`synchronous = ${opts?.synchronous ?? 'FULL'}`);
22
39
  this.db.pragma('foreign_keys = ON');
23
40
  this.db.pragma('busy_timeout = 5000');
24
41
  this._createTables();
42
+ if (this.encryptionKey) {
43
+ this._encryptExistingData();
44
+ }
25
45
  }
26
46
  checkpoint() {
27
47
  this.db.pragma('wal_checkpoint(TRUNCATE)');
@@ -32,6 +52,38 @@ class SqliteStorage {
32
52
  async backup(destPath) {
33
53
  await this.db.backup(destPath);
34
54
  }
55
+ _encryptExistingData() {
56
+ const key = this.encryptionKey;
57
+ if (!key)
58
+ return;
59
+ this.db.transaction(() => {
60
+ for (const { table, pk, columns } of SqliteStorage.ENCRYPTED_COLUMNS) {
61
+ const rows = this.db
62
+ .prepare(`SELECT ${pk}, ${columns.join(', ')} FROM ${table}`)
63
+ .all();
64
+ for (const row of rows) {
65
+ const updates = [];
66
+ const params = [];
67
+ for (const col of columns) {
68
+ const raw = row[col];
69
+ if (raw === null || raw === undefined)
70
+ continue;
71
+ const text = typeof raw === 'string' ? raw : String(raw);
72
+ if ((0, encryption_1.isEncryptedValue)(text))
73
+ continue;
74
+ updates.push(`${col} = ?`);
75
+ params.push((0, encryption_1.encryptValue)(key, text));
76
+ }
77
+ if (updates.length === 0)
78
+ continue;
79
+ params.push(row[pk]);
80
+ this.db
81
+ .prepare(`UPDATE ${table} SET ${updates.join(', ')} WHERE ${pk} = ?`)
82
+ .run(...params);
83
+ }
84
+ }
85
+ })();
86
+ }
35
87
  _createTables() {
36
88
  this.db.exec(`
37
89
  CREATE TABLE IF NOT EXISTS channels (
@@ -152,6 +204,63 @@ class SqliteStorage {
152
204
  created_at INTEGER NOT NULL,
153
205
  completed_at INTEGER
154
206
  );
207
+
208
+ CREATE TABLE IF NOT EXISTS channel_policies (
209
+ channel_id TEXT PRIMARY KEY,
210
+ policy_json TEXT NOT NULL
211
+ );
212
+
213
+ CREATE TABLE IF NOT EXISTS peer_storage_blobs (
214
+ peer_pubkey TEXT PRIMARY KEY,
215
+ blob TEXT NOT NULL,
216
+ received_at INTEGER NOT NULL
217
+ );
218
+
219
+ CREATE TABLE IF NOT EXISTS forwarding_events (
220
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
221
+ settled_at INTEGER NOT NULL,
222
+ in_channel_id TEXT NOT NULL,
223
+ out_channel_id TEXT NOT NULL,
224
+ in_scid TEXT,
225
+ out_scid TEXT,
226
+ amount_in_msat TEXT NOT NULL,
227
+ amount_out_msat TEXT NOT NULL,
228
+ fee_msat TEXT NOT NULL
229
+ );
230
+ CREATE INDEX IF NOT EXISTS idx_forwarding_events_settled_at ON forwarding_events(settled_at);
231
+
232
+ CREATE TABLE IF NOT EXISTS watchtower_sessions (
233
+ session_id TEXT PRIMARY KEY,
234
+ tower_uri TEXT NOT NULL,
235
+ tower_pubkey TEXT NOT NULL,
236
+ session_key TEXT NOT NULL,
237
+ blob_type INTEGER NOT NULL,
238
+ max_updates INTEGER NOT NULL,
239
+ sweep_fee_rate TEXT NOT NULL,
240
+ seq_num INTEGER NOT NULL,
241
+ last_applied INTEGER NOT NULL,
242
+ created_at INTEGER NOT NULL,
243
+ dials_with_session_key INTEGER NOT NULL DEFAULT 0
244
+ );
245
+ CREATE INDEX IF NOT EXISTS idx_watchtower_sessions_tower ON watchtower_sessions(tower_uri);
246
+
247
+ CREATE TABLE IF NOT EXISTS watchtower_updates (
248
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
249
+ tower_uri TEXT NOT NULL,
250
+ channel_id TEXT NOT NULL,
251
+ hint TEXT NOT NULL,
252
+ encrypted_blob TEXT NOT NULL,
253
+ seq_num INTEGER NOT NULL,
254
+ acked INTEGER NOT NULL,
255
+ created_at INTEGER NOT NULL,
256
+ blob_type INTEGER NOT NULL DEFAULT 2
257
+ );
258
+ CREATE INDEX IF NOT EXISTS idx_watchtower_updates_pending ON watchtower_updates(tower_uri, acked);
259
+
260
+ CREATE TABLE IF NOT EXISTS wallet_data (
261
+ key TEXT PRIMARY KEY,
262
+ value TEXT NOT NULL
263
+ );
155
264
  `);
156
265
  this._runMigrations();
157
266
  }
@@ -160,7 +269,7 @@ class SqliteStorage {
160
269
  const json = JSON.stringify(serialized);
161
270
  this.db
162
271
  .prepare('INSERT OR REPLACE INTO channels (channel_id, state_json, peer_pubkey) VALUES (?, ?, ?)')
163
- .run(id, json, peerPubkey);
272
+ .run(id, this._enc(json), peerPubkey);
164
273
  }
165
274
  loadChannel(id) {
166
275
  const row = this.db
@@ -169,7 +278,7 @@ class SqliteStorage {
169
278
  if (!row)
170
279
  return null;
171
280
  return {
172
- state: (0, serialization_1.deserializeChannelState)(JSON.parse(row.state_json)),
281
+ state: (0, serialization_1.deserializeChannelState)(JSON.parse(this._dec(row.state_json))),
173
282
  peerPubkey: row.peer_pubkey
174
283
  };
175
284
  }
@@ -182,7 +291,7 @@ class SqliteStorage {
182
291
  try {
183
292
  results.push({
184
293
  channelId: row.channel_id,
185
- state: (0, serialization_1.deserializeChannelState)(JSON.parse(row.state_json)),
294
+ state: (0, serialization_1.deserializeChannelState)(JSON.parse(this._dec(row.state_json))),
186
295
  peerPubkey: row.peer_pubkey
187
296
  });
188
297
  }
@@ -200,7 +309,7 @@ class SqliteStorage {
200
309
  const json = JSON.stringify(serialized);
201
310
  this.db
202
311
  .prepare('INSERT OR REPLACE INTO payments (payment_hash, payment_json) VALUES (?, ?)')
203
- .run(paymentHash, json);
312
+ .run(paymentHash, this._enc(json));
204
313
  }
205
314
  loadPayment(paymentHash) {
206
315
  const row = this.db
@@ -208,7 +317,7 @@ class SqliteStorage {
208
317
  .get(paymentHash);
209
318
  if (!row)
210
319
  return null;
211
- return (0, serialization_1.deserializePaymentInfo)(JSON.parse(row.payment_json));
320
+ return (0, serialization_1.deserializePaymentInfo)(JSON.parse(this._dec(row.payment_json)));
212
321
  }
213
322
  loadAllPayments() {
214
323
  const rows = this.db
@@ -219,7 +328,7 @@ class SqliteStorage {
219
328
  try {
220
329
  results.push({
221
330
  paymentHash: row.payment_hash,
222
- payment: (0, serialization_1.deserializePaymentInfo)(JSON.parse(row.payment_json))
331
+ payment: (0, serialization_1.deserializePaymentInfo)(JSON.parse(this._dec(row.payment_json)))
223
332
  });
224
333
  }
225
334
  catch (err) {
@@ -236,7 +345,7 @@ class SqliteStorage {
236
345
  savePreimage(paymentHash, preimage) {
237
346
  this.db
238
347
  .prepare('INSERT OR REPLACE INTO preimages (payment_hash, preimage) VALUES (?, ?)')
239
- .run(paymentHash, preimage.toString('hex'));
348
+ .run(paymentHash, this._enc(preimage.toString('hex')));
240
349
  }
241
350
  loadPreimage(paymentHash) {
242
351
  const row = this.db
@@ -244,7 +353,7 @@ class SqliteStorage {
244
353
  .get(paymentHash);
245
354
  if (!row)
246
355
  return null;
247
- return Buffer.from(row.preimage, 'hex');
356
+ return Buffer.from(this._dec(row.preimage), 'hex');
248
357
  }
249
358
  loadAllPreimages() {
250
359
  const rows = this.db
@@ -255,7 +364,7 @@ class SqliteStorage {
255
364
  try {
256
365
  results.push({
257
366
  paymentHash: row.payment_hash,
258
- preimage: Buffer.from(row.preimage, 'hex')
367
+ preimage: Buffer.from(this._dec(row.preimage), 'hex')
259
368
  });
260
369
  }
261
370
  catch (err) {
@@ -290,7 +399,7 @@ class SqliteStorage {
290
399
  saveHtlcPaymentMapping(key, paymentHashHex) {
291
400
  this.db
292
401
  .prepare('INSERT OR REPLACE INTO htlc_payment_map (htlc_key, payment_hash_hex) VALUES (?, ?)')
293
- .run(key, paymentHashHex);
402
+ .run(key, this._enc(paymentHashHex));
294
403
  }
295
404
  loadAllHtlcPaymentMappings() {
296
405
  const rows = this.db
@@ -301,7 +410,7 @@ class SqliteStorage {
301
410
  try {
302
411
  results.push({
303
412
  key: row.htlc_key,
304
- paymentHashHex: row.payment_hash_hex
413
+ paymentHashHex: this._dec(row.payment_hash_hex)
305
414
  });
306
415
  }
307
416
  catch (err) {
@@ -316,7 +425,7 @@ class SqliteStorage {
316
425
  saveForwardedHtlc(outKey, inChannelId, inHtlcId) {
317
426
  this.db
318
427
  .prepare('INSERT OR REPLACE INTO forwarded_htlcs (out_key, in_channel_id, in_htlc_id) VALUES (?, ?, ?)')
319
- .run(outKey, inChannelId.toString('hex'), inHtlcId.toString());
428
+ .run(outKey, this._enc(inChannelId.toString('hex')), this._enc(inHtlcId.toString()));
320
429
  }
321
430
  loadAllForwardedHtlcs() {
322
431
  const rows = this.db
@@ -327,8 +436,8 @@ class SqliteStorage {
327
436
  try {
328
437
  results.push({
329
438
  outKey: row.out_key,
330
- inChannelId: Buffer.from(row.in_channel_id, 'hex'),
331
- inHtlcId: BigInt(row.in_htlc_id)
439
+ inChannelId: Buffer.from(this._dec(row.in_channel_id), 'hex'),
440
+ inHtlcId: BigInt(this._dec(row.in_htlc_id))
332
441
  });
333
442
  }
334
443
  catch (err) {
@@ -346,7 +455,7 @@ class SqliteStorage {
346
455
  const json = (0, serialization_1.serializeChainMonitorState)(state);
347
456
  this.db
348
457
  .prepare('INSERT OR REPLACE INTO chain_monitors (channel_id, state_json) VALUES (?, ?)')
349
- .run(channelId, json);
458
+ .run(channelId, this._enc(json));
350
459
  }
351
460
  loadChainMonitor(channelId) {
352
461
  const row = this.db
@@ -354,7 +463,7 @@ class SqliteStorage {
354
463
  .get(channelId);
355
464
  if (!row)
356
465
  return null;
357
- return (0, serialization_1.deserializeChainMonitorState)(row.state_json);
466
+ return (0, serialization_1.deserializeChainMonitorState)(this._dec(row.state_json));
358
467
  }
359
468
  loadAllChainMonitors() {
360
469
  const rows = this.db
@@ -365,7 +474,7 @@ class SqliteStorage {
365
474
  try {
366
475
  results.push({
367
476
  channelId: row.channel_id,
368
- state: (0, serialization_1.deserializeChainMonitorState)(row.state_json)
477
+ state: (0, serialization_1.deserializeChainMonitorState)(this._dec(row.state_json))
369
478
  });
370
479
  }
371
480
  catch (err) {
@@ -424,7 +533,7 @@ class SqliteStorage {
424
533
  savePaymentSecret(paymentHashHex, secret) {
425
534
  this.db
426
535
  .prepare('INSERT OR REPLACE INTO payment_secrets (payment_hash_hex, secret) VALUES (?, ?)')
427
- .run(paymentHashHex, secret.toString('hex'));
536
+ .run(paymentHashHex, this._enc(secret.toString('hex')));
428
537
  }
429
538
  loadAllPaymentSecrets() {
430
539
  const rows = this.db
@@ -435,7 +544,7 @@ class SqliteStorage {
435
544
  try {
436
545
  results.push({
437
546
  paymentHashHex: row.payment_hash_hex,
438
- secret: Buffer.from(row.secret, 'hex')
547
+ secret: Buffer.from(this._dec(row.secret), 'hex')
439
548
  });
440
549
  }
441
550
  catch (err) {
@@ -459,11 +568,12 @@ class SqliteStorage {
459
568
  description: invoice.description,
460
569
  expiry: invoice.expiry,
461
570
  createdAt: invoice.createdAt,
462
- hold: invoice.hold
571
+ hold: invoice.hold,
572
+ cancelledAt: invoice.cancelledAt
463
573
  });
464
574
  this.db
465
575
  .prepare('INSERT OR REPLACE INTO invoices (payment_hash_hex, invoice_json) VALUES (?, ?)')
466
- .run(paymentHashHex, json);
576
+ .run(paymentHashHex, this._enc(json));
467
577
  }
468
578
  loadAllInvoices() {
469
579
  const rows = this.db
@@ -472,7 +582,7 @@ class SqliteStorage {
472
582
  const results = [];
473
583
  for (const row of rows) {
474
584
  try {
475
- const parsed = JSON.parse(row.invoice_json);
585
+ const parsed = JSON.parse(this._dec(row.invoice_json));
476
586
  results.push({
477
587
  paymentHashHex: row.payment_hash_hex,
478
588
  invoice: {
@@ -484,7 +594,8 @@ class SqliteStorage {
484
594
  description: parsed.description,
485
595
  expiry: parsed.expiry,
486
596
  createdAt: parsed.createdAt,
487
- hold: parsed.hold
597
+ hold: parsed.hold,
598
+ cancelledAt: parsed.cancelledAt
488
599
  }
489
600
  });
490
601
  }
@@ -527,24 +638,33 @@ class SqliteStorage {
527
638
  saveChannelKeyIndex(channelId, channelIndex) {
528
639
  this.db
529
640
  .prepare('INSERT OR REPLACE INTO channel_key_indices (channel_id, channel_index) VALUES (?, ?)')
530
- .run(channelId, channelIndex);
641
+ .run(channelId, this.encryptionKey ? this._enc(String(channelIndex)) : channelIndex);
642
+ }
643
+ _decodeChannelIndex(value) {
644
+ return typeof value === 'number' ? value : Number(this._dec(value));
531
645
  }
532
646
  loadChannelKeyIndex(channelId) {
533
647
  const row = this.db
534
648
  .prepare('SELECT channel_index FROM channel_key_indices WHERE channel_id = ?')
535
649
  .get(channelId);
536
- return row ? row.channel_index : null;
650
+ return row ? this._decodeChannelIndex(row.channel_index) : null;
537
651
  }
538
652
  loadNextChannelIndex() {
539
- const row = this.db
540
- .prepare('SELECT MAX(channel_index) as max_idx FROM channel_key_indices')
541
- .get();
542
- return row && row.max_idx !== null ? row.max_idx + 1 : 1;
653
+ const rows = this.db
654
+ .prepare('SELECT channel_index FROM channel_key_indices')
655
+ .all();
656
+ let maxIdx = null;
657
+ for (const row of rows) {
658
+ const idx = this._decodeChannelIndex(row.channel_index);
659
+ if (maxIdx === null || idx > maxIdx)
660
+ maxIdx = idx;
661
+ }
662
+ return maxIdx !== null ? maxIdx + 1 : 1;
543
663
  }
544
664
  saveHtlcSharedSecret(key, secret) {
545
665
  this.db
546
666
  .prepare('INSERT OR REPLACE INTO htlc_shared_secrets (key, secret) VALUES (?, ?)')
547
- .run(key, secret.toString('hex'));
667
+ .run(key, this._enc(secret.toString('hex')));
548
668
  }
549
669
  deleteHtlcSharedSecret(key) {
550
670
  this.db.prepare('DELETE FROM htlc_shared_secrets WHERE key = ?').run(key);
@@ -558,7 +678,7 @@ class SqliteStorage {
558
678
  try {
559
679
  results.push({
560
680
  key: row.key,
561
- secret: Buffer.from(row.secret, 'hex')
681
+ secret: Buffer.from(this._dec(row.secret), 'hex')
562
682
  });
563
683
  }
564
684
  catch (err) {
@@ -621,6 +741,30 @@ class SqliteStorage {
621
741
  }
622
742
  },
623
743
  () => {
744
+ },
745
+ () => {
746
+ },
747
+ () => {
748
+ },
749
+ () => {
750
+ },
751
+ () => {
752
+ },
753
+ () => {
754
+ },
755
+ () => {
756
+ },
757
+ (db) => {
758
+ try {
759
+ db.exec('ALTER TABLE watchtower_updates ADD COLUMN blob_type INTEGER NOT NULL DEFAULT 2');
760
+ }
761
+ catch {
762
+ }
763
+ try {
764
+ db.exec('ALTER TABLE watchtower_sessions ADD COLUMN dials_with_session_key INTEGER NOT NULL DEFAULT 0');
765
+ }
766
+ catch {
767
+ }
624
768
  }
625
769
  ];
626
770
  for (let v = currentVersion; v < targetVersion; v++) {
@@ -646,6 +790,202 @@ class SqliteStorage {
646
790
  .get(key);
647
791
  return row ? row.value : null;
648
792
  }
793
+ saveWalletData(key, value) {
794
+ this.db
795
+ .prepare('INSERT OR REPLACE INTO wallet_data (key, value) VALUES (?, ?)')
796
+ .run(key, this._enc(value));
797
+ }
798
+ loadWalletData(key) {
799
+ const row = this.db
800
+ .prepare('SELECT value FROM wallet_data WHERE key = ?')
801
+ .get(key);
802
+ return row ? this._dec(row.value) : null;
803
+ }
804
+ saveChannelPolicy(channelId, policy) {
805
+ this.db
806
+ .prepare('INSERT OR REPLACE INTO channel_policies (channel_id, policy_json) VALUES (?, ?)')
807
+ .run(channelId, JSON.stringify(policy));
808
+ }
809
+ loadAllChannelPolicies() {
810
+ const rows = this.db
811
+ .prepare('SELECT channel_id, policy_json FROM channel_policies')
812
+ .all();
813
+ const results = [];
814
+ for (const row of rows) {
815
+ try {
816
+ results.push({
817
+ channelId: row.channel_id,
818
+ policy: JSON.parse(row.policy_json)
819
+ });
820
+ }
821
+ catch (err) {
822
+ this.reportCorruptRow(err);
823
+ }
824
+ }
825
+ return results;
826
+ }
827
+ deleteChannelPolicy(channelId) {
828
+ this.db
829
+ .prepare('DELETE FROM channel_policies WHERE channel_id = ?')
830
+ .run(channelId);
831
+ }
832
+ savePeerStorageBlob(peerPubkey, blob, receivedAt) {
833
+ this.db
834
+ .prepare('INSERT OR REPLACE INTO peer_storage_blobs (peer_pubkey, blob, received_at) VALUES (?, ?, ?)')
835
+ .run(peerPubkey, this._enc(blob.toString('base64')), receivedAt);
836
+ }
837
+ loadPeerStorageBlob(peerPubkey) {
838
+ const row = this.db
839
+ .prepare('SELECT blob, received_at FROM peer_storage_blobs WHERE peer_pubkey = ?')
840
+ .get(peerPubkey);
841
+ if (!row)
842
+ return null;
843
+ return {
844
+ blob: Buffer.from(this._dec(row.blob), 'base64'),
845
+ receivedAt: row.received_at
846
+ };
847
+ }
848
+ deletePeerStorageBlob(peerPubkey) {
849
+ this.db
850
+ .prepare('DELETE FROM peer_storage_blobs WHERE peer_pubkey = ?')
851
+ .run(peerPubkey);
852
+ }
853
+ saveWatchtowerSession(session, sessionKey) {
854
+ this.db
855
+ .prepare(`INSERT OR REPLACE INTO watchtower_sessions
856
+ (session_id, tower_uri, tower_pubkey, session_key, blob_type,
857
+ max_updates, sweep_fee_rate, seq_num, last_applied, created_at,
858
+ dials_with_session_key)
859
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
860
+ .run(session.sessionId, session.towerUri, session.towerPubkey, this._enc(sessionKey.toString('base64')), session.blobType, session.maxUpdates, session.sweepFeeRate, session.seqNum, session.lastApplied, session.createdAt, session.dialsWithSessionKey ? 1 : 0);
861
+ }
862
+ loadWatchtowerSessions() {
863
+ const rows = this.db
864
+ .prepare('SELECT * FROM watchtower_sessions')
865
+ .all();
866
+ return rows.map((r) => ({
867
+ sessionId: r.session_id,
868
+ towerUri: r.tower_uri,
869
+ towerPubkey: r.tower_pubkey,
870
+ sessionKey: Buffer.from(this._dec(r.session_key), 'base64'),
871
+ blobType: r.blob_type,
872
+ maxUpdates: r.max_updates,
873
+ sweepFeeRate: r.sweep_fee_rate,
874
+ seqNum: r.seq_num,
875
+ lastApplied: r.last_applied,
876
+ createdAt: r.created_at,
877
+ dialsWithSessionKey: r.dials_with_session_key === 1
878
+ }));
879
+ }
880
+ setWatchtowerSessionProgress(sessionId, seqNum, lastApplied) {
881
+ this.db
882
+ .prepare('UPDATE watchtower_sessions SET seq_num = ?, last_applied = ? WHERE session_id = ?')
883
+ .run(seqNum, lastApplied, sessionId);
884
+ }
885
+ deleteWatchtowerTower(towerUri) {
886
+ this.db.transaction(() => {
887
+ this.db
888
+ .prepare('DELETE FROM watchtower_sessions WHERE tower_uri = ?')
889
+ .run(towerUri);
890
+ this.db
891
+ .prepare('DELETE FROM watchtower_updates WHERE tower_uri = ?')
892
+ .run(towerUri);
893
+ })();
894
+ }
895
+ addWatchtowerUpdate(update) {
896
+ const info = this.db
897
+ .prepare(`INSERT INTO watchtower_updates
898
+ (tower_uri, channel_id, hint, encrypted_blob, seq_num, acked,
899
+ created_at, blob_type)
900
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
901
+ .run(update.towerUri, update.channelId, update.hint, this._enc(update.encryptedBlob), update.seqNum, update.acked ? 1 : 0, update.createdAt, update.blobType);
902
+ return Number(info.lastInsertRowid);
903
+ }
904
+ loadPendingWatchtowerUpdates() {
905
+ const rows = this.db
906
+ .prepare('SELECT * FROM watchtower_updates WHERE acked = 0 ORDER BY id ASC')
907
+ .all();
908
+ return rows.map((r) => ({
909
+ id: r.id,
910
+ towerUri: r.tower_uri,
911
+ channelId: r.channel_id,
912
+ blobType: r.blob_type,
913
+ hint: r.hint,
914
+ encryptedBlob: this._dec(r.encrypted_blob),
915
+ seqNum: r.seq_num,
916
+ acked: r.acked === 1,
917
+ createdAt: r.created_at
918
+ }));
919
+ }
920
+ markWatchtowerUpdateAcked(id, seqNum) {
921
+ this.db
922
+ .prepare('UPDATE watchtower_updates SET acked = 1, seq_num = ? WHERE id = ?')
923
+ .run(seqNum, id);
924
+ }
925
+ saveForwardingEvent(event) {
926
+ this.db
927
+ .prepare(`INSERT INTO forwarding_events
928
+ (settled_at, in_channel_id, out_channel_id, in_scid, out_scid,
929
+ amount_in_msat, amount_out_msat, fee_msat)
930
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
931
+ .run(event.settledAt, event.inChannelId, event.outChannelId, event.inScid ?? null, event.outScid ?? null, event.amountInMsat.toString(), event.amountOutMsat.toString(), event.feeMsat.toString());
932
+ this.db
933
+ .prepare('DELETE FROM forwarding_events WHERE id NOT IN (SELECT id FROM forwarding_events ORDER BY id DESC LIMIT ?)')
934
+ .run(this.forwardingEventsMaxRows);
935
+ }
936
+ listForwardingEvents(filter) {
937
+ let sql = 'SELECT id, settled_at, in_channel_id, out_channel_id, in_scid, out_scid, amount_in_msat, amount_out_msat, fee_msat FROM forwarding_events WHERE 1=1';
938
+ const params = [];
939
+ if (filter?.since !== undefined) {
940
+ sql += ' AND settled_at >= ?';
941
+ params.push(filter.since);
942
+ }
943
+ if (filter?.until !== undefined) {
944
+ sql += ' AND settled_at <= ?';
945
+ params.push(filter.until);
946
+ }
947
+ if (filter?.channelId !== undefined) {
948
+ sql += ' AND (in_channel_id = ? OR out_channel_id = ?)';
949
+ params.push(filter.channelId, filter.channelId);
950
+ }
951
+ sql += ' ORDER BY settled_at DESC, id DESC';
952
+ sql += ' LIMIT ?';
953
+ params.push(filter?.limit !== undefined && filter.limit > 0 ? filter.limit : 1000);
954
+ if (filter?.offset !== undefined && filter.offset > 0) {
955
+ sql += ' OFFSET ?';
956
+ params.push(filter.offset);
957
+ }
958
+ const rows = this.db.prepare(sql).all(...params);
959
+ return rows.map((row) => ({
960
+ id: row.id,
961
+ settledAt: row.settled_at,
962
+ inChannelId: row.in_channel_id,
963
+ outChannelId: row.out_channel_id,
964
+ inScid: row.in_scid ?? undefined,
965
+ outScid: row.out_scid ?? undefined,
966
+ amountInMsat: BigInt(row.amount_in_msat),
967
+ amountOutMsat: BigInt(row.amount_out_msat),
968
+ feeMsat: BigInt(row.fee_msat)
969
+ }));
970
+ }
971
+ getForwardingSummary(options) {
972
+ let sql = 'SELECT amount_out_msat, fee_msat FROM forwarding_events WHERE 1=1';
973
+ const params = [];
974
+ if (options?.since !== undefined) {
975
+ sql += ' AND settled_at >= ?';
976
+ params.push(options.since);
977
+ }
978
+ let count = 0;
979
+ let volumeOutMsat = 0n;
980
+ let feesEarnedMsat = 0n;
981
+ for (const row of this.db.prepare(sql).iterate(...params)) {
982
+ const r = row;
983
+ count++;
984
+ volumeOutMsat += BigInt(r.amount_out_msat);
985
+ feesEarnedMsat += BigInt(r.fee_msat);
986
+ }
987
+ return { count, volumeOutMsat, feesEarnedMsat };
988
+ }
649
989
  transaction(fn) {
650
990
  return this.db.transaction(fn)();
651
991
  }
@@ -713,5 +1053,37 @@ class SqliteStorage {
713
1053
  }
714
1054
  }
715
1055
  exports.SqliteStorage = SqliteStorage;
716
- SqliteStorage.CURRENT_SCHEMA_VERSION = 2;
1056
+ SqliteStorage.CURRENT_SCHEMA_VERSION = 9;
1057
+ SqliteStorage.ENCRYPTED_COLUMNS = [
1058
+ { table: 'channels', pk: 'channel_id', columns: ['state_json'] },
1059
+ { table: 'payments', pk: 'payment_hash', columns: ['payment_json'] },
1060
+ { table: 'preimages', pk: 'payment_hash', columns: ['preimage'] },
1061
+ {
1062
+ table: 'htlc_payment_map',
1063
+ pk: 'htlc_key',
1064
+ columns: ['payment_hash_hex']
1065
+ },
1066
+ {
1067
+ table: 'forwarded_htlcs',
1068
+ pk: 'out_key',
1069
+ columns: ['in_channel_id', 'in_htlc_id']
1070
+ },
1071
+ { table: 'chain_monitors', pk: 'channel_id', columns: ['state_json'] },
1072
+ { table: 'payment_secrets', pk: 'payment_hash_hex', columns: ['secret'] },
1073
+ { table: 'htlc_shared_secrets', pk: 'key', columns: ['secret'] },
1074
+ { table: 'invoices', pk: 'payment_hash_hex', columns: ['invoice_json'] },
1075
+ {
1076
+ table: 'channel_key_indices',
1077
+ pk: 'channel_id',
1078
+ columns: ['channel_index']
1079
+ },
1080
+ { table: 'peer_storage_blobs', pk: 'peer_pubkey', columns: ['blob'] },
1081
+ {
1082
+ table: 'watchtower_sessions',
1083
+ pk: 'session_id',
1084
+ columns: ['session_key']
1085
+ },
1086
+ { table: 'watchtower_updates', pk: 'id', columns: ['encrypted_blob'] },
1087
+ { table: 'wallet_data', pk: 'key', columns: ['value'] }
1088
+ ];
717
1089
  //# sourceMappingURL=sqlite-storage.js.map