@breeztech/breez-sdk-spark 0.6.6 → 0.7.1

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.
@@ -198,6 +198,44 @@ class MigrationManager {
198
198
  store.clear();
199
199
  }
200
200
  }
201
+ },
202
+ {
203
+ name: "Clear sync tables for BreezSigner backward compatibility",
204
+ upgrade: (db, transaction) => {
205
+ // Clear all sync tables due to BreezSigner signature change.
206
+ // This forces users to sync from scratch to the sync server.
207
+ // Also delete the sync_initial_complete flag to force re-populating
208
+ // all payment metadata for outgoing sync using the new key.
209
+
210
+ // Clear sync tables (only if they exist)
211
+ if (db.objectStoreNames.contains("sync_outgoing")) {
212
+ const syncOutgoing = transaction.objectStore("sync_outgoing");
213
+ syncOutgoing.clear();
214
+ }
215
+
216
+ if (db.objectStoreNames.contains("sync_incoming")) {
217
+ const syncIncoming = transaction.objectStore("sync_incoming");
218
+ syncIncoming.clear();
219
+ }
220
+
221
+ if (db.objectStoreNames.contains("sync_state")) {
222
+ const syncState = transaction.objectStore("sync_state");
223
+ syncState.clear();
224
+ }
225
+
226
+ // Reset revision to 0 (only if store exists)
227
+ if (db.objectStoreNames.contains("sync_revision")) {
228
+ const syncRevision = transaction.objectStore("sync_revision");
229
+ syncRevision.clear();
230
+ syncRevision.put({ id: 1, revision: "0" });
231
+ }
232
+
233
+ // Delete sync_initial_complete setting (only if store exists)
234
+ if (db.objectStoreNames.contains("settings")) {
235
+ const settings = transaction.objectStore("settings");
236
+ settings.delete("sync_initial_complete");
237
+ }
238
+ }
201
239
  }
202
240
  ];
203
241
  }
@@ -222,7 +260,7 @@ class IndexedDBStorage {
222
260
  this.db = null;
223
261
  this.migrationManager = null;
224
262
  this.logger = logger;
225
- this.dbVersion = 6; // Current schema version
263
+ this.dbVersion = 7; // Current schema version
226
264
  }
227
265
 
228
266
  /**
@@ -420,12 +458,6 @@ class IndexedDBStorage {
420
458
 
421
459
  const payment = cursor.value;
422
460
 
423
- // Apply filters
424
- if (!this._matchesFilters(payment, request)) {
425
- cursor.continue();
426
- return;
427
- }
428
-
429
461
  if (skipped < actualOffset) {
430
462
  skipped++;
431
463
  cursor.continue();
@@ -440,6 +472,12 @@ class IndexedDBStorage {
440
472
  payment,
441
473
  metadata
442
474
  );
475
+
476
+ // Apply filters
477
+ if (!this._matchesFilters(paymentWithMetadata, request)) {
478
+ cursor.continue();
479
+ return;
480
+ }
443
481
 
444
482
  // Fetch lnurl receive metadata if it's a lightning payment
445
483
  this._fetchLnurlReceiveMetadata(paymentWithMetadata, lnurlReceiveMetadataStore)
@@ -457,8 +495,11 @@ class IndexedDBStorage {
457
495
  };
458
496
  metadataRequest.onerror = () => {
459
497
  // Continue without metadata if it fails
460
- payments.push(payment);
461
- count++;
498
+ if (this._matchesFilters(payment, request)) {
499
+ payments.push(payment);
500
+ count++;
501
+ }
502
+
462
503
  cursor.continue();
463
504
  };
464
505
  };
@@ -637,6 +678,7 @@ class IndexedDBStorage {
637
678
 
638
679
  const metadataToStore = {
639
680
  paymentId,
681
+ parentPaymentId: metadata.parentPaymentId,
640
682
  lnurlPayInfo: metadata.lnurlPayInfo
641
683
  ? JSON.stringify(metadata.lnurlPayInfo)
642
684
  : null,
@@ -644,6 +686,9 @@ class IndexedDBStorage {
644
686
  ? JSON.stringify(metadata.lnurlWithdrawInfo)
645
687
  : null,
646
688
  lnurlDescription: metadata.lnurlDescription,
689
+ tokenConversionInfo: metadata.tokenConversionInfo
690
+ ? JSON.stringify(metadata.tokenConversionInfo)
691
+ : null,
647
692
  };
648
693
 
649
694
  const request = store.put(metadataToStore);
@@ -1456,11 +1501,8 @@ class IndexedDBStorage {
1456
1501
  }
1457
1502
  }
1458
1503
 
1459
- // Filter by Spark HTLC status
1460
- if (
1461
- request.sparkHtlcStatusFilter &&
1462
- request.sparkHtlcStatusFilter.length > 0
1463
- ) {
1504
+ // Filter by payment details
1505
+ if (request.paymentDetailsFilter && request.paymentDetailsFilter.length > 0) {
1464
1506
  let details = null;
1465
1507
 
1466
1508
  // Parse details if it's a string (stored in IndexedDB)
@@ -1475,12 +1517,66 @@ class IndexedDBStorage {
1475
1517
  details = payment.details;
1476
1518
  }
1477
1519
 
1478
- // Only Spark payments can have HTLC details
1479
- if (!details || details.type !== "spark" || !details.htlcDetails) {
1520
+ if (!details) {
1480
1521
  return false;
1481
1522
  }
1482
1523
 
1483
- if (!request.sparkHtlcStatusFilter.includes(details.htlcDetails.status)) {
1524
+ // Filter by payment details. If any filter matches, we include the payment
1525
+ let paymentDetailsFilterMatches = false;
1526
+ for (const paymentDetailsFilter of request.paymentDetailsFilter) {
1527
+ // Filter by Spark HTLC status
1528
+ if (
1529
+ paymentDetailsFilter.type === "spark" &&
1530
+ paymentDetailsFilter.htlcStatus != null &&
1531
+ paymentDetailsFilter.htlcStatus.length > 0
1532
+ ) {
1533
+ if (
1534
+ details.type !== "spark" ||
1535
+ !details.htlcDetails ||
1536
+ !paymentDetailsFilter.htlcStatus.includes(details.htlcDetails.status)
1537
+ ) {
1538
+ continue;
1539
+ }
1540
+ }
1541
+ // Filter by token conversion info presence
1542
+ if (
1543
+ (paymentDetailsFilter.type === "spark" ||
1544
+ paymentDetailsFilter.type === "token") &&
1545
+ paymentDetailsFilter.conversionRefundNeeded != null
1546
+ ) {
1547
+ if (
1548
+ details.type !== paymentDetailsFilter.type ||
1549
+ !details.tokenConversionInfo
1550
+ ) {
1551
+ continue;
1552
+ }
1553
+
1554
+ if (
1555
+ details.tokenConversionInfo.paymentId ||
1556
+ paymentDetailsFilter.conversionRefundNeeded ===
1557
+ !!details.tokenConversionInfo.refundIdentifier
1558
+ ) {
1559
+ continue;
1560
+ }
1561
+ }
1562
+ // Filter by token transaction hash
1563
+ if (
1564
+ paymentDetailsFilter.type === "token" &&
1565
+ paymentDetailsFilter.txHash != null
1566
+ ) {
1567
+ if (
1568
+ details.type !== "token" ||
1569
+ details.txHash !== paymentDetailsFilter.txHash
1570
+ ) {
1571
+ continue;
1572
+ }
1573
+ }
1574
+
1575
+ paymentDetailsFilterMatches = true;
1576
+ break;
1577
+ }
1578
+
1579
+ if (!paymentDetailsFilterMatches) {
1484
1580
  return false;
1485
1581
  }
1486
1582
  }
@@ -1555,31 +1651,44 @@ class IndexedDBStorage {
1555
1651
  }
1556
1652
  }
1557
1653
 
1558
- // If this is a Lightning payment and we have metadata
1559
- if (metadata && details && details.type == "lightning") {
1560
- if (metadata.lnurlDescription && !details.description) {
1561
- details.description = metadata.lnurlDescription;
1562
- }
1563
- // If lnurlPayInfo exists, parse and add to details
1564
- if (metadata.lnurlPayInfo) {
1565
- try {
1566
- details.lnurlPayInfo = JSON.parse(metadata.lnurlPayInfo);
1567
- } catch (e) {
1568
- throw new StorageError(
1569
- `Failed to parse lnurlPayInfo JSON for payment ${payment.id}: ${e.message}`,
1570
- e
1571
- );
1654
+ if (metadata && details) {
1655
+ if (details.type == "lightning") {
1656
+ if (metadata.lnurlDescription && !details.description) {
1657
+ details.description = metadata.lnurlDescription;
1572
1658
  }
1573
- }
1574
- // If lnurlWithdrawInfo exists, parse and add to details
1575
- if (metadata.lnurlWithdrawInfo) {
1576
- try {
1577
- details.lnurlWithdrawInfo = JSON.parse(metadata.lnurlWithdrawInfo);
1578
- } catch (e) {
1579
- throw new StorageError(
1580
- `Failed to parse lnurlWithdrawInfo JSON for payment ${payment.id}: ${e.message}`,
1581
- e
1582
- );
1659
+ // If lnurlPayInfo exists, parse and add to details
1660
+ if (metadata.lnurlPayInfo) {
1661
+ try {
1662
+ details.lnurlPayInfo = JSON.parse(metadata.lnurlPayInfo);
1663
+ } catch (e) {
1664
+ throw new StorageError(
1665
+ `Failed to parse lnurlPayInfo JSON for payment ${payment.id}: ${e.message}`,
1666
+ e
1667
+ );
1668
+ }
1669
+ }
1670
+ // If lnurlWithdrawInfo exists, parse and add to details
1671
+ if (metadata.lnurlWithdrawInfo) {
1672
+ try {
1673
+ details.lnurlWithdrawInfo = JSON.parse(metadata.lnurlWithdrawInfo);
1674
+ } catch (e) {
1675
+ throw new StorageError(
1676
+ `Failed to parse lnurlWithdrawInfo JSON for payment ${payment.id}: ${e.message}`,
1677
+ e
1678
+ );
1679
+ }
1680
+ }
1681
+ } else if (details.type == "spark" || details.type == "token") {
1682
+ // If tokenConversionInfo exists, parse and add to details
1683
+ if (metadata.tokenConversionInfo) {
1684
+ try {
1685
+ details.tokenConversionInfo = JSON.parse(metadata.tokenConversionInfo);
1686
+ } catch (e) {
1687
+ throw new StorageError(
1688
+ `Failed to parse tokenConversionInfo JSON for payment ${payment.id}: ${e.message}`,
1689
+ e
1690
+ );
1691
+ }
1583
1692
  }
1584
1693
  }
1585
1694
  }