@breeztech/breez-sdk-spark 0.8.0-dev1 → 0.8.3-dev1

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.
@@ -217,27 +217,6 @@ function debugString(val) {
217
217
  // TODO we could test for more things here, like `Set`s and `Map`s.
218
218
  return className;
219
219
  }
220
- /**
221
- * @param {Config} config
222
- * @param {ExternalSigner} signer
223
- * @param {string} storage_dir
224
- * @returns {Promise<BreezSdk>}
225
- */
226
- module.exports.connectWithSigner = function(config, signer, storage_dir) {
227
- const ptr0 = passStringToWasm0(storage_dir, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
228
- const len0 = WASM_VECTOR_LEN;
229
- const ret = wasm.connectWithSigner(config, signer, ptr0, len0);
230
- return ret;
231
- };
232
-
233
- /**
234
- * @param {ConnectRequest} request
235
- * @returns {Promise<BreezSdk>}
236
- */
237
- module.exports.connect = function(request) {
238
- const ret = wasm.connect(request);
239
- return ret;
240
- };
241
220
 
242
221
  function takeFromExternrefTable0(idx) {
243
222
  const value = wasm.__wbindgen_export_5.get(idx);
@@ -263,6 +242,15 @@ module.exports.defaultExternalSigner = function(mnemonic, passphrase, network, k
263
242
  return DefaultSigner.__wrap(ret[0]);
264
243
  };
265
244
 
245
+ /**
246
+ * @param {ConnectRequest} request
247
+ * @returns {Promise<BreezSdk>}
248
+ */
249
+ module.exports.connect = function(request) {
250
+ const ret = wasm.connect(request);
251
+ return ret;
252
+ };
253
+
266
254
  /**
267
255
  * @param {Logger} logger
268
256
  * @param {string | null} [filter]
@@ -276,13 +264,15 @@ module.exports.initLogging = function(logger, filter) {
276
264
  };
277
265
 
278
266
  /**
279
- * Creates a default external signer from a mnemonic phrase.
280
- *
281
- * This creates a signer that can be used with `connectWithSigner` or `SdkBuilder.newWithSigner`.
282
- * @returns {Promise<SparkStatus>}
267
+ * @param {Config} config
268
+ * @param {ExternalSigner} signer
269
+ * @param {string} storage_dir
270
+ * @returns {Promise<BreezSdk>}
283
271
  */
284
- module.exports.getSparkStatus = function() {
285
- const ret = wasm.getSparkStatus();
272
+ module.exports.connectWithSigner = function(config, signer, storage_dir) {
273
+ const ptr0 = passStringToWasm0(storage_dir, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
274
+ const len0 = WASM_VECTOR_LEN;
275
+ const ret = wasm.connectWithSigner(config, signer, ptr0, len0);
286
276
  return ret;
287
277
  };
288
278
 
@@ -295,6 +285,17 @@ module.exports.defaultConfig = function(network) {
295
285
  return ret;
296
286
  };
297
287
 
288
+ /**
289
+ * Creates a default external signer from a mnemonic phrase.
290
+ *
291
+ * This creates a signer that can be used with `connectWithSigner` or `SdkBuilder.newWithSigner`.
292
+ * @returns {Promise<SparkStatus>}
293
+ */
294
+ module.exports.getSparkStatus = function() {
295
+ const ret = wasm.getSparkStatus();
296
+ return ret;
297
+ };
298
+
298
299
  function passArray8ToWasm0(arg, malloc) {
299
300
  const ptr = malloc(arg.length * 1, 1) >>> 0;
300
301
  getUint8ArrayMemory0().set(arg, ptr / 1);
@@ -313,15 +314,15 @@ module.exports.task_worker_entry_point = function(ptr) {
313
314
  };
314
315
 
315
316
  function __wbg_adapter_64(arg0, arg1) {
316
- wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hf2ef52c8a8b47594(arg0, arg1);
317
+ wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h127c718764a2a72f(arg0, arg1);
317
318
  }
318
319
 
319
320
  function __wbg_adapter_67(arg0, arg1, arg2) {
320
- wasm.closure1078_externref_shim(arg0, arg1, arg2);
321
+ wasm.closure1090_externref_shim(arg0, arg1, arg2);
321
322
  }
322
323
 
323
- function __wbg_adapter_287(arg0, arg1, arg2, arg3) {
324
- wasm.closure671_externref_shim(arg0, arg1, arg2, arg3);
324
+ function __wbg_adapter_285(arg0, arg1, arg2, arg3) {
325
+ wasm.closure670_externref_shim(arg0, arg1, arg2, arg3);
325
326
  }
326
327
 
327
328
  const __wbindgen_enum_ReadableStreamType = ["bytes"];
@@ -1879,7 +1880,7 @@ module.exports.__wbg_new_23a2665fac83c611 = function(arg0, arg1) {
1879
1880
  const a = state0.a;
1880
1881
  state0.a = 0;
1881
1882
  try {
1882
- return __wbg_adapter_287(a, state0.b, arg0, arg1);
1883
+ return __wbg_adapter_285(a, state0.b, arg0, arg1);
1883
1884
  } finally {
1884
1885
  state0.a = a;
1885
1886
  }
@@ -2291,11 +2292,6 @@ module.exports.__wbg_syncInsertIncomingRecords_dde4039dbc9cb38f = function() { r
2291
2292
  return ret;
2292
2293
  }, arguments) };
2293
2294
 
2294
- module.exports.__wbg_syncRebasePendingOutgoingRecords_b3441ced5dee0c8e = function() { return handleError(function (arg0, arg1) {
2295
- const ret = arg0.syncRebasePendingOutgoingRecords(BigInt.asUintN(64, arg1));
2296
- return ret;
2297
- }, arguments) };
2298
-
2299
2295
  module.exports.__wbg_syncUpdateRecordFromIncoming_a76ad82592bfdcb3 = function() { return handleError(function (arg0, arg1) {
2300
2296
  const ret = arg0.syncUpdateRecordFromIncoming(arg1);
2301
2297
  return ret;
@@ -2409,13 +2405,13 @@ module.exports.__wbindgen_cb_drop = function(arg0) {
2409
2405
  return ret;
2410
2406
  };
2411
2407
 
2412
- module.exports.__wbindgen_closure_wrapper11759 = function(arg0, arg1, arg2) {
2413
- const ret = makeMutClosure(arg0, arg1, 848, __wbg_adapter_64);
2408
+ module.exports.__wbindgen_closure_wrapper11879 = function(arg0, arg1, arg2) {
2409
+ const ret = makeMutClosure(arg0, arg1, 851, __wbg_adapter_64);
2414
2410
  return ret;
2415
2411
  };
2416
2412
 
2417
- module.exports.__wbindgen_closure_wrapper13708 = function(arg0, arg1, arg2) {
2418
- const ret = makeMutClosure(arg0, arg1, 1079, __wbg_adapter_67);
2413
+ module.exports.__wbindgen_closure_wrapper13824 = function(arg0, arg1, arg2) {
2414
+ const ret = makeMutClosure(arg0, arg1, 1091, __wbg_adapter_67);
2419
2415
  return ret;
2420
2416
  };
2421
2417
 
Binary file
@@ -113,7 +113,7 @@ export const __wbindgen_export_5: WebAssembly.Table;
113
113
  export const __externref_drop_slice: (a: number, b: number) => void;
114
114
  export const __wbindgen_export_7: WebAssembly.Table;
115
115
  export const __externref_table_dealloc: (a: number) => void;
116
- export const _dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hf2ef52c8a8b47594: (a: number, b: number) => void;
117
- export const closure1078_externref_shim: (a: number, b: number, c: any) => void;
118
- export const closure671_externref_shim: (a: number, b: number, c: any, d: any) => void;
116
+ export const _dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h127c718764a2a72f: (a: number, b: number) => void;
117
+ export const closure1090_externref_shim: (a: number, b: number, c: any) => void;
118
+ export const closure670_externref_shim: (a: number, b: number, c: any, d: any) => void;
119
119
  export const __wbindgen_start: () => void;
@@ -48,6 +48,8 @@ const SELECT_PAYMENT_SQL = `
48
48
  l.destination_pubkey AS lightning_destination_pubkey,
49
49
  COALESCE(l.description, pm.lnurl_description) AS lightning_description,
50
50
  l.preimage AS lightning_preimage,
51
+ l.htlc_status AS lightning_htlc_status,
52
+ l.htlc_expiry_time AS lightning_htlc_expiry_time,
51
53
  pm.lnurl_pay_info,
52
54
  pm.lnurl_withdraw_info,
53
55
  pm.conversion_info,
@@ -200,18 +202,30 @@ class SqliteStorage {
200
202
  const allPaymentDetailsClauses = [];
201
203
  for (const paymentDetailsFilter of request.paymentDetailsFilter) {
202
204
  const paymentDetailsClauses = [];
203
- // Filter by Spark HTLC status
205
+ // Filter by HTLC status (Spark or Lightning)
206
+ const htlcAlias =
207
+ paymentDetailsFilter.type === "spark" ? "s"
208
+ : paymentDetailsFilter.type === "lightning" ? "l"
209
+ : null;
204
210
  if (
205
- paymentDetailsFilter.type === "spark" &&
211
+ htlcAlias &&
206
212
  paymentDetailsFilter.htlcStatus !== undefined &&
207
213
  paymentDetailsFilter.htlcStatus.length > 0
208
214
  ) {
209
215
  const placeholders = paymentDetailsFilter.htlcStatus
210
216
  .map(() => "?")
211
217
  .join(", ");
212
- paymentDetailsClauses.push(
213
- `json_extract(s.htlc_details, '$.status') IN (${placeholders})`
214
- );
218
+ if (htlcAlias === "l") {
219
+ // Lightning: htlc_status is a direct column
220
+ paymentDetailsClauses.push(
221
+ `l.htlc_status IN (${placeholders})`
222
+ );
223
+ } else {
224
+ // Spark: htlc_details is still JSON
225
+ paymentDetailsClauses.push(
226
+ `json_extract(s.htlc_details, '$.status') IN (${placeholders})`
227
+ );
228
+ }
215
229
  params.push(...paymentDetailsFilter.htlcStatus);
216
230
  }
217
231
  // Filter by token conversion info presence
@@ -246,6 +260,7 @@ class SqliteStorage {
246
260
  params.push(paymentDetailsFilter.txType);
247
261
  }
248
262
 
263
+
249
264
  if (paymentDetailsClauses.length > 0) {
250
265
  allPaymentDetailsClauses.push(`(${paymentDetailsClauses.join(" AND ")})`);
251
266
  }
@@ -321,15 +336,17 @@ class SqliteStorage {
321
336
  spark=excluded.spark`
322
337
  );
323
338
  const lightningInsert = this.db.prepare(
324
- `INSERT INTO payment_details_lightning
325
- (payment_id, invoice, payment_hash, destination_pubkey, description, preimage)
326
- VALUES (@id, @invoice, @paymentHash, @destinationPubkey, @description, @preimage)
339
+ `INSERT INTO payment_details_lightning
340
+ (payment_id, invoice, payment_hash, destination_pubkey, description, preimage, htlc_status, htlc_expiry_time)
341
+ VALUES (@id, @invoice, @paymentHash, @destinationPubkey, @description, @preimage, @htlcStatus, @htlcExpiryTime)
327
342
  ON CONFLICT(payment_id) DO UPDATE SET
328
343
  invoice=excluded.invoice,
329
344
  payment_hash=excluded.payment_hash,
330
345
  destination_pubkey=excluded.destination_pubkey,
331
346
  description=excluded.description,
332
- preimage=excluded.preimage`
347
+ preimage=COALESCE(excluded.preimage, payment_details_lightning.preimage),
348
+ htlc_status=COALESCE(excluded.htlc_status, payment_details_lightning.htlc_status),
349
+ htlc_expiry_time=COALESCE(excluded.htlc_expiry_time, payment_details_lightning.htlc_expiry_time)`
333
350
  );
334
351
  const tokenInsert = this.db.prepare(
335
352
  `INSERT INTO payment_details_token
@@ -385,10 +402,12 @@ class SqliteStorage {
385
402
  lightningInsert.run({
386
403
  id: payment.id,
387
404
  invoice: payment.details.invoice,
388
- paymentHash: payment.details.paymentHash,
405
+ paymentHash: payment.details.htlcDetails.paymentHash,
389
406
  destinationPubkey: payment.details.destinationPubkey,
390
407
  description: payment.details.description,
391
- preimage: payment.details.preimage,
408
+ preimage: payment.details.htlcDetails?.preimage,
409
+ htlcStatus: payment.details.htlcDetails?.status || null,
410
+ htlcExpiryTime: payment.details.htlcDetails?.expiryTime || 0,
392
411
  });
393
412
  }
394
413
 
@@ -696,10 +715,16 @@ class SqliteStorage {
696
715
  details = {
697
716
  type: "lightning",
698
717
  invoice: row.lightning_invoice,
699
- paymentHash: row.lightning_payment_hash,
700
718
  destinationPubkey: row.lightning_destination_pubkey,
701
719
  description: row.lightning_description,
702
- preimage: row.lightning_preimage,
720
+ htlcDetails: row.lightning_htlc_status
721
+ ? {
722
+ paymentHash: row.lightning_payment_hash,
723
+ preimage: row.lightning_preimage || null,
724
+ expiryTime: row.lightning_htlc_expiry_time || 0,
725
+ status: row.lightning_htlc_status,
726
+ }
727
+ : (() => { throw new StorageError(`htlc_status is required for Lightning payment ${row.id}`); })(),
703
728
  };
704
729
 
705
730
  if (row.lnurl_pay_info) {
@@ -798,14 +823,10 @@ class SqliteStorage {
798
823
  syncAddOutgoingChange(record) {
799
824
  try {
800
825
  const transaction = this.db.transaction(() => {
801
- // Compute next revision as max(committed, max outgoing) + 1, without updating sync_revision
826
+ // This revision is a local queue id for pending rows, not a server revision.
802
827
  const revisionQuery = this.db.prepare(`
803
- SELECT CAST(
804
- MAX(
805
- (SELECT revision FROM sync_revision),
806
- COALESCE((SELECT MAX(revision) FROM sync_outgoing), 0)
807
- ) + 1
808
- AS TEXT) AS revision
828
+ SELECT CAST(COALESCE(MAX(revision), 0) + 1 AS TEXT) AS revision
829
+ FROM sync_outgoing
809
830
  `);
810
831
  const revision = BigInt(revisionQuery.get().revision);
811
832
 
@@ -931,7 +952,7 @@ class SqliteStorage {
931
952
  },
932
953
  schemaVersion: row.schema_version,
933
954
  updatedFields: JSON.parse(row.updated_fields_json),
934
- revision: BigInt(row.revision),
955
+ localRevision: BigInt(row.revision),
935
956
  };
936
957
 
937
958
  let parent = null;
@@ -1042,50 +1063,6 @@ class SqliteStorage {
1042
1063
  }
1043
1064
  }
1044
1065
 
1045
- syncRebasePendingOutgoingRecords(revision) {
1046
- try {
1047
- const transaction = this.db.transaction(() => {
1048
- // Get current committed revision from sync_revision table
1049
- const getLastRevisionStmt = this.db.prepare(`
1050
- SELECT CAST(revision AS TEXT) as last_revision FROM sync_revision
1051
- `);
1052
- const revisionRow = getLastRevisionStmt.get();
1053
- const lastRevision = revisionRow
1054
- ? BigInt(revisionRow.last_revision)
1055
- : BigInt(0);
1056
-
1057
- // Calculate the difference to add to all revision numbers
1058
- const diff =
1059
- revision > lastRevision ? revision - lastRevision : BigInt(0);
1060
-
1061
- if (diff > BigInt(0)) {
1062
- // Update all pending outgoing records
1063
- const updateRecordsStmt = this.db.prepare(`
1064
- UPDATE sync_outgoing
1065
- SET revision = revision + CAST(? AS INTEGER)
1066
- `);
1067
- updateRecordsStmt.run(diff.toString());
1068
- }
1069
-
1070
- // Update sync_revision within the same transaction so retries are idempotent
1071
- const updateRevisionStmt = this.db.prepare(`
1072
- UPDATE sync_revision SET revision = MAX(revision, CAST(? AS INTEGER))
1073
- `);
1074
- updateRevisionStmt.run(revision.toString());
1075
- });
1076
-
1077
- transaction();
1078
- return Promise.resolve();
1079
- } catch (error) {
1080
- return Promise.reject(
1081
- new StorageError(
1082
- `Failed to rebase pending outgoing records: ${error.message}`,
1083
- error
1084
- )
1085
- );
1086
- }
1087
- }
1088
-
1089
1066
  syncGetIncomingRecords(limit) {
1090
1067
  try {
1091
1068
  const transaction = this.db.transaction(() => {
@@ -1191,7 +1168,7 @@ class SqliteStorage {
1191
1168
  },
1192
1169
  schemaVersion: row.schema_version,
1193
1170
  updatedFields: JSON.parse(row.updated_fields_json),
1194
- revision: BigInt(row.revision),
1171
+ localRevision: BigInt(row.revision),
1195
1172
  };
1196
1173
 
1197
1174
  let parent = null;
@@ -13,11 +13,12 @@ class MigrationManager {
13
13
  }
14
14
 
15
15
  /**
16
- * Run all pending migrations
16
+ * Run all pending migrations, or up to a specific version.
17
+ * @param {number|null} targetVersion - Target version to migrate to (default: latest)
17
18
  */
18
- migrate() {
19
+ migrate(targetVersion = null) {
19
20
  const currentVersion = this._getCurrentVersion();
20
- const targetVersion = this.migrations.length;
21
+ targetVersion = targetVersion ?? this.migrations.length;
21
22
 
22
23
  if (currentVersion >= targetVersion) {
23
24
  this._log("info", `Database is up to date (version ${currentVersion})`);
@@ -345,6 +346,27 @@ class MigrationManager {
345
346
  `DELETE FROM settings WHERE key = 'sync_initial_complete'`
346
347
  ]
347
348
  },
349
+ {
350
+ name: "Add htlc_status and htlc_expiry_time to lightning payments",
351
+ sql: [
352
+ `ALTER TABLE payment_details_lightning ADD COLUMN htlc_status TEXT NOT NULL DEFAULT 'waitingForPreimage'`,
353
+ `ALTER TABLE payment_details_lightning ADD COLUMN htlc_expiry_time INTEGER NOT NULL DEFAULT 0`,
354
+ ]
355
+ },
356
+ {
357
+ name: "Backfill htlc_status for existing Lightning payments",
358
+ sql: [
359
+ `UPDATE payment_details_lightning
360
+ SET htlc_status = CASE
361
+ WHEN (SELECT status FROM payments WHERE id = payment_id) = 'completed' THEN 'preimageShared'
362
+ WHEN (SELECT status FROM payments WHERE id = payment_id) = 'pending' THEN 'waitingForPreimage'
363
+ ELSE 'returned'
364
+ END`,
365
+ `UPDATE settings
366
+ SET value = json_set(value, '$.offset', 0)
367
+ WHERE key = 'sync_offset' AND json_valid(value)`,
368
+ ]
369
+ },
348
370
  ];
349
371
  }
350
372
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@breeztech/breez-sdk-spark",
3
- "version": "0.8.0-dev1",
3
+ "version": "0.8.3-dev1",
4
4
  "description": "Breez Spark SDK",
5
5
  "repository": "https://github.com/breez/spark-sdk",
6
6
  "author": "Breez <contact@breez.technology> (https://github.com/breez)",