@bopen-io/wallet-toolbox 1.7.19 → 1.7.20-idb-fix.2
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.
- package/SECURITY-ISSUE-WPM-TOKEN-THEFT.md +218 -0
- package/WPM-vulnerability.md +23 -0
- package/out/src/sdk/validationHelpers.d.ts +303 -0
- package/out/src/sdk/validationHelpers.d.ts.map +1 -0
- package/out/src/sdk/validationHelpers.js +632 -0
- package/out/src/sdk/validationHelpers.js.map +1 -0
- package/out/src/storage/StorageIdb.d.ts.map +1 -1
- package/out/src/storage/StorageIdb.js +166 -82
- package/out/src/storage/StorageIdb.js.map +1 -1
- package/out/src/storage/methods/createAction.js +22 -7
- package/out/src/storage/methods/createAction.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/storage/StorageIdb.ts +192 -78
- package/src/storage/methods/createAction.ts +23 -7
- package/.claude/settings.local.json +0 -14
|
@@ -75,6 +75,16 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
75
75
|
toDbTrx(stores, mode, trx) {
|
|
76
76
|
if (trx) {
|
|
77
77
|
const t = trx;
|
|
78
|
+
// Check if the transaction is still active by trying to access an object store
|
|
79
|
+
try {
|
|
80
|
+
const storeToCheck = stores[0] || this.allStores[0];
|
|
81
|
+
t.objectStore(storeToCheck);
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
console.error(`[StorageIdb.toDbTrx] Passed transaction already finished! stores=${stores.join(',')}, mode=${mode}`);
|
|
85
|
+
console.error('[StorageIdb.toDbTrx] Stack trace:', new Error().stack);
|
|
86
|
+
throw e;
|
|
87
|
+
}
|
|
78
88
|
return t;
|
|
79
89
|
}
|
|
80
90
|
else {
|
|
@@ -290,7 +300,8 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
290
300
|
* @returns next funding output to add to transaction or undefined if there are none.
|
|
291
301
|
*/
|
|
292
302
|
async allocateChangeInput(userId, basketId, targetSatoshis, exactSatoshis, excludeSending, transactionId) {
|
|
293
|
-
|
|
303
|
+
// Include proven_txs in store list since findOutputs -> validateOutputScript needs it
|
|
304
|
+
const dbTrx = this.toDbTrx(['outputs', 'transactions', 'proven_txs'], 'readwrite');
|
|
294
305
|
try {
|
|
295
306
|
const txStatus = ['completed', 'unproven'];
|
|
296
307
|
if (!excludeSending)
|
|
@@ -444,19 +455,30 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
444
455
|
}
|
|
445
456
|
async filterOutputTagMaps(args, filtered, userId) {
|
|
446
457
|
var _a, _b, _c, _d;
|
|
458
|
+
// Pre-compute outputTagIds for this user BEFORE opening cursor.
|
|
459
|
+
// This avoids nested queries inside the cursor loop which cause IDB transaction timeouts.
|
|
460
|
+
let userOutputTagIds;
|
|
461
|
+
if (userId !== undefined) {
|
|
462
|
+
userOutputTagIds = new Set();
|
|
463
|
+
const userTags = await this.findOutputTags({ partial: { userId } });
|
|
464
|
+
for (const tag of userTags) {
|
|
465
|
+
userOutputTagIds.add(tag.outputTagId);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
447
468
|
const offset = ((_a = args.paged) === null || _a === void 0 ? void 0 : _a.offset) || 0;
|
|
448
469
|
let skipped = 0;
|
|
449
470
|
let count = 0;
|
|
450
471
|
const dbTrx = this.toDbTrx(['output_tags_map'], 'readonly', args.trx);
|
|
472
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
451
473
|
let cursor;
|
|
452
474
|
if (((_b = args.partial) === null || _b === void 0 ? void 0 : _b.outputTagId) !== undefined) {
|
|
453
|
-
cursor = await dbTrx.objectStore('output_tags_map').index('outputTagId').openCursor(args.partial.outputTagId);
|
|
475
|
+
cursor = await dbTrx.objectStore('output_tags_map').index('outputTagId').openCursor(args.partial.outputTagId, direction);
|
|
454
476
|
}
|
|
455
477
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.outputId) !== undefined) {
|
|
456
|
-
cursor = await dbTrx.objectStore('output_tags_map').index('outputId').openCursor(args.partial.outputId);
|
|
478
|
+
cursor = await dbTrx.objectStore('output_tags_map').index('outputId').openCursor(args.partial.outputId, direction);
|
|
457
479
|
}
|
|
458
480
|
else {
|
|
459
|
-
cursor = await dbTrx.objectStore('output_tags_map').openCursor();
|
|
481
|
+
cursor = await dbTrx.objectStore('output_tags_map').openCursor(null, direction);
|
|
460
482
|
}
|
|
461
483
|
let firstTime = true;
|
|
462
484
|
while (cursor) {
|
|
@@ -482,10 +504,8 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
482
504
|
if (args.partial.isDeleted !== undefined && r.isDeleted !== args.partial.isDeleted)
|
|
483
505
|
continue;
|
|
484
506
|
}
|
|
485
|
-
if (
|
|
486
|
-
|
|
487
|
-
if (count === 0)
|
|
488
|
-
continue;
|
|
507
|
+
if (userOutputTagIds !== undefined && !userOutputTagIds.has(r.outputTagId)) {
|
|
508
|
+
continue;
|
|
489
509
|
}
|
|
490
510
|
if (skipped < offset) {
|
|
491
511
|
skipped++;
|
|
@@ -512,28 +532,41 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
512
532
|
throw new WERR_errors_1.WERR_INVALID_PARAMETER('args.partial.rawTx', `undefined. ProvenTxReqs may not be found by rawTx value.`);
|
|
513
533
|
if (args.partial.inputBEEF)
|
|
514
534
|
throw new WERR_errors_1.WERR_INVALID_PARAMETER('args.partial.inputBEEF', `undefined. ProvenTxReqs may not be found by inputBEEF value.`);
|
|
535
|
+
// Pre-compute txids for this user's transactions BEFORE opening cursor.
|
|
536
|
+
// This avoids nested queries inside the cursor loop which cause IDB transaction timeouts.
|
|
537
|
+
let userTxIds;
|
|
538
|
+
if (userId !== undefined) {
|
|
539
|
+
userTxIds = new Set();
|
|
540
|
+
const userTxs = await this.findTransactions({ partial: { userId }, noRawTx: true });
|
|
541
|
+
for (const tx of userTxs) {
|
|
542
|
+
if (tx.txid) {
|
|
543
|
+
userTxIds.add(tx.txid);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
515
547
|
const offset = ((_a = args.paged) === null || _a === void 0 ? void 0 : _a.offset) || 0;
|
|
516
548
|
let skipped = 0;
|
|
517
549
|
let count = 0;
|
|
518
550
|
const dbTrx = this.toDbTrx(['proven_tx_reqs'], 'readonly', args.trx);
|
|
551
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
519
552
|
let cursor;
|
|
520
553
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.provenTxReqId) {
|
|
521
|
-
cursor = await dbTrx.objectStore('proven_tx_reqs').openCursor(args.partial.provenTxReqId);
|
|
554
|
+
cursor = await dbTrx.objectStore('proven_tx_reqs').openCursor(args.partial.provenTxReqId, direction);
|
|
522
555
|
}
|
|
523
556
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.provenTxId) !== undefined) {
|
|
524
|
-
cursor = await dbTrx.objectStore('proven_tx_reqs').index('provenTxId').openCursor(args.partial.provenTxId);
|
|
557
|
+
cursor = await dbTrx.objectStore('proven_tx_reqs').index('provenTxId').openCursor(args.partial.provenTxId, direction);
|
|
525
558
|
}
|
|
526
559
|
else if (((_d = args.partial) === null || _d === void 0 ? void 0 : _d.txid) !== undefined) {
|
|
527
|
-
cursor = await dbTrx.objectStore('proven_tx_reqs').index('txid').openCursor(args.partial.txid);
|
|
560
|
+
cursor = await dbTrx.objectStore('proven_tx_reqs').index('txid').openCursor(args.partial.txid, direction);
|
|
528
561
|
}
|
|
529
562
|
else if (((_e = args.partial) === null || _e === void 0 ? void 0 : _e.status) !== undefined) {
|
|
530
|
-
cursor = await dbTrx.objectStore('proven_tx_reqs').index('status').openCursor(args.partial.status);
|
|
563
|
+
cursor = await dbTrx.objectStore('proven_tx_reqs').index('status').openCursor(args.partial.status, direction);
|
|
531
564
|
}
|
|
532
565
|
else if (((_f = args.partial) === null || _f === void 0 ? void 0 : _f.batch) !== undefined) {
|
|
533
|
-
cursor = await dbTrx.objectStore('proven_tx_reqs').index('batch').openCursor(args.partial.batch);
|
|
566
|
+
cursor = await dbTrx.objectStore('proven_tx_reqs').index('batch').openCursor(args.partial.batch, direction);
|
|
534
567
|
}
|
|
535
568
|
else {
|
|
536
|
-
cursor = await dbTrx.objectStore('proven_tx_reqs').openCursor();
|
|
569
|
+
cursor = await dbTrx.objectStore('proven_tx_reqs').openCursor(null, direction);
|
|
537
570
|
}
|
|
538
571
|
let firstTime = true;
|
|
539
572
|
while (cursor) {
|
|
@@ -545,6 +578,10 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
545
578
|
const r = cursor.value;
|
|
546
579
|
if (args.since && args.since > r.updated_at)
|
|
547
580
|
continue;
|
|
581
|
+
if (args.status && args.status.length > 0 && !args.status.includes(r.status))
|
|
582
|
+
continue;
|
|
583
|
+
if (args.txids && args.txids.length > 0 && !args.txids.includes(r.txid))
|
|
584
|
+
continue;
|
|
548
585
|
if (args.partial) {
|
|
549
586
|
if (args.partial.provenTxReqId && r.provenTxReqId !== args.partial.provenTxReqId)
|
|
550
587
|
continue;
|
|
@@ -569,10 +606,8 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
569
606
|
if (args.partial.notify && r.notify !== args.partial.notify)
|
|
570
607
|
continue;
|
|
571
608
|
}
|
|
572
|
-
if (
|
|
573
|
-
|
|
574
|
-
if (count === 0)
|
|
575
|
-
continue;
|
|
609
|
+
if (userTxIds !== undefined && r.txid && !userTxIds.has(r.txid)) {
|
|
610
|
+
continue;
|
|
576
611
|
}
|
|
577
612
|
if (skipped < offset) {
|
|
578
613
|
skipped++;
|
|
@@ -599,19 +634,32 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
599
634
|
throw new WERR_errors_1.WERR_INVALID_PARAMETER('args.partial.rawTx', `undefined. ProvenTxs may not be found by rawTx value.`);
|
|
600
635
|
if (args.partial.merklePath)
|
|
601
636
|
throw new WERR_errors_1.WERR_INVALID_PARAMETER('args.partial.merklePath', `undefined. ProvenTxs may not be found by merklePath value.`);
|
|
637
|
+
// Pre-compute provenTxIds for this user's transactions BEFORE opening cursor.
|
|
638
|
+
// This avoids nested queries inside the cursor loop which cause IDB transaction timeouts.
|
|
639
|
+
let userProvenTxIds;
|
|
640
|
+
if (userId !== undefined) {
|
|
641
|
+
userProvenTxIds = new Set();
|
|
642
|
+
const userTxs = await this.findTransactions({ partial: { userId }, noRawTx: true });
|
|
643
|
+
for (const tx of userTxs) {
|
|
644
|
+
if (tx.provenTxId !== undefined) {
|
|
645
|
+
userProvenTxIds.add(tx.provenTxId);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
602
649
|
const offset = ((_a = args.paged) === null || _a === void 0 ? void 0 : _a.offset) || 0;
|
|
603
650
|
let skipped = 0;
|
|
604
651
|
let count = 0;
|
|
605
652
|
const dbTrx = this.toDbTrx(['proven_txs'], 'readonly', args.trx);
|
|
653
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
606
654
|
let cursor;
|
|
607
655
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.provenTxId) {
|
|
608
|
-
cursor = await dbTrx.objectStore('proven_txs').openCursor(args.partial.provenTxId);
|
|
656
|
+
cursor = await dbTrx.objectStore('proven_txs').openCursor(args.partial.provenTxId, direction);
|
|
609
657
|
}
|
|
610
658
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.txid) !== undefined) {
|
|
611
|
-
cursor = await dbTrx.objectStore('proven_txs').index('txid').openCursor(args.partial.txid);
|
|
659
|
+
cursor = await dbTrx.objectStore('proven_txs').index('txid').openCursor(args.partial.txid, direction);
|
|
612
660
|
}
|
|
613
661
|
else {
|
|
614
|
-
cursor = await dbTrx.objectStore('proven_txs').openCursor();
|
|
662
|
+
cursor = await dbTrx.objectStore('proven_txs').openCursor(null, direction);
|
|
615
663
|
}
|
|
616
664
|
let firstTime = true;
|
|
617
665
|
while (cursor) {
|
|
@@ -641,10 +689,8 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
641
689
|
if (args.partial.merkleRoot && r.merkleRoot !== args.partial.merkleRoot)
|
|
642
690
|
continue;
|
|
643
691
|
}
|
|
644
|
-
if (
|
|
645
|
-
|
|
646
|
-
if (count === 0)
|
|
647
|
-
continue;
|
|
692
|
+
if (userProvenTxIds !== undefined && !userProvenTxIds.has(r.provenTxId)) {
|
|
693
|
+
continue;
|
|
648
694
|
}
|
|
649
695
|
if (skipped < offset) {
|
|
650
696
|
skipped++;
|
|
@@ -667,19 +713,30 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
667
713
|
}
|
|
668
714
|
async filterTxLabelMaps(args, filtered, userId) {
|
|
669
715
|
var _a, _b, _c, _d;
|
|
716
|
+
// Pre-compute txLabelIds for this user BEFORE opening cursor.
|
|
717
|
+
// This avoids nested queries inside the cursor loop which cause IDB transaction timeouts.
|
|
718
|
+
let userTxLabelIds;
|
|
719
|
+
if (userId !== undefined) {
|
|
720
|
+
userTxLabelIds = new Set();
|
|
721
|
+
const userLabels = await this.findTxLabels({ partial: { userId } });
|
|
722
|
+
for (const label of userLabels) {
|
|
723
|
+
userTxLabelIds.add(label.txLabelId);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
670
726
|
const offset = ((_a = args.paged) === null || _a === void 0 ? void 0 : _a.offset) || 0;
|
|
671
727
|
let skipped = 0;
|
|
672
728
|
let count = 0;
|
|
673
729
|
const dbTrx = this.toDbTrx(['tx_labels_map'], 'readonly', args.trx);
|
|
730
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
674
731
|
let cursor;
|
|
675
732
|
if (((_b = args.partial) === null || _b === void 0 ? void 0 : _b.transactionId) !== undefined) {
|
|
676
|
-
cursor = await dbTrx.objectStore('tx_labels_map').index('transactionId').openCursor(args.partial.transactionId);
|
|
733
|
+
cursor = await dbTrx.objectStore('tx_labels_map').index('transactionId').openCursor(args.partial.transactionId, direction);
|
|
677
734
|
}
|
|
678
735
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.txLabelId) !== undefined) {
|
|
679
|
-
cursor = await dbTrx.objectStore('tx_labels_map').index('txLabelId').openCursor(args.partial.txLabelId);
|
|
736
|
+
cursor = await dbTrx.objectStore('tx_labels_map').index('txLabelId').openCursor(args.partial.txLabelId, direction);
|
|
680
737
|
}
|
|
681
738
|
else {
|
|
682
|
-
cursor = await dbTrx.objectStore('tx_labels_map').openCursor();
|
|
739
|
+
cursor = await dbTrx.objectStore('tx_labels_map').openCursor(null, direction);
|
|
683
740
|
}
|
|
684
741
|
let firstTime = true;
|
|
685
742
|
while (cursor) {
|
|
@@ -691,6 +748,8 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
691
748
|
const r = cursor.value;
|
|
692
749
|
if (args.since && args.since > r.updated_at)
|
|
693
750
|
continue;
|
|
751
|
+
if (args.labelIds && !args.labelIds.includes(r.txLabelId))
|
|
752
|
+
continue;
|
|
694
753
|
if (args.partial) {
|
|
695
754
|
if (args.partial.txLabelId && r.txLabelId !== args.partial.txLabelId)
|
|
696
755
|
continue;
|
|
@@ -703,10 +762,8 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
703
762
|
if (args.partial.isDeleted !== undefined && r.isDeleted !== args.partial.isDeleted)
|
|
704
763
|
continue;
|
|
705
764
|
}
|
|
706
|
-
if (
|
|
707
|
-
|
|
708
|
-
if (count === 0)
|
|
709
|
-
continue;
|
|
765
|
+
if (userTxLabelIds !== undefined && !userTxLabelIds.has(r.txLabelId)) {
|
|
766
|
+
continue;
|
|
710
767
|
}
|
|
711
768
|
if (skipped < offset) {
|
|
712
769
|
skipped++;
|
|
@@ -999,7 +1056,14 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
999
1056
|
}
|
|
1000
1057
|
const u = this.validatePartialForUpdate(update);
|
|
1001
1058
|
const dbTrx = this.toDbTrx([storeName], 'readwrite', trx);
|
|
1002
|
-
|
|
1059
|
+
let store;
|
|
1060
|
+
try {
|
|
1061
|
+
store = dbTrx.objectStore(storeName);
|
|
1062
|
+
}
|
|
1063
|
+
catch (e) {
|
|
1064
|
+
console.error(`[StorageIdb.updateIdb] objectStore('${storeName}') failed for id=${JSON.stringify(id)}, trx=${!!trx}:`, e);
|
|
1065
|
+
throw e;
|
|
1066
|
+
}
|
|
1003
1067
|
const ids = Array.isArray(id) ? id : [id];
|
|
1004
1068
|
try {
|
|
1005
1069
|
for (const i of ids) {
|
|
@@ -1124,7 +1188,14 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1124
1188
|
return r;
|
|
1125
1189
|
}
|
|
1126
1190
|
catch (err) {
|
|
1127
|
-
|
|
1191
|
+
// Log more detail about transaction errors to help debug IDB issues
|
|
1192
|
+
console.error('[StorageIdb] Transaction error:', err instanceof Error ? err.message : err);
|
|
1193
|
+
try {
|
|
1194
|
+
tx.abort();
|
|
1195
|
+
}
|
|
1196
|
+
catch (abortErr) {
|
|
1197
|
+
console.error('[StorageIdb] Error aborting transaction:', abortErr);
|
|
1198
|
+
}
|
|
1128
1199
|
await tx.done;
|
|
1129
1200
|
throw err;
|
|
1130
1201
|
}
|
|
@@ -1135,18 +1206,19 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1135
1206
|
let skipped = 0;
|
|
1136
1207
|
let count = 0;
|
|
1137
1208
|
const dbTrx = this.toDbTrx(['certificate_fields'], 'readonly', args.trx);
|
|
1209
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1138
1210
|
let cursor;
|
|
1139
1211
|
if (((_b = args.partial) === null || _b === void 0 ? void 0 : _b.certificateId) !== undefined) {
|
|
1140
1212
|
cursor = await dbTrx
|
|
1141
1213
|
.objectStore('certificate_fields')
|
|
1142
1214
|
.index('certificateId')
|
|
1143
|
-
.openCursor(args.partial.certificateId);
|
|
1215
|
+
.openCursor(args.partial.certificateId, direction);
|
|
1144
1216
|
}
|
|
1145
1217
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.userId) !== undefined) {
|
|
1146
|
-
cursor = await dbTrx.objectStore('certificate_fields').index('userId').openCursor(args.partial.userId);
|
|
1218
|
+
cursor = await dbTrx.objectStore('certificate_fields').index('userId').openCursor(args.partial.userId, direction);
|
|
1147
1219
|
}
|
|
1148
1220
|
else {
|
|
1149
|
-
cursor = await dbTrx.objectStore('certificate_fields').openCursor();
|
|
1221
|
+
cursor = await dbTrx.objectStore('certificate_fields').openCursor(null, direction);
|
|
1150
1222
|
}
|
|
1151
1223
|
let firstTime = true;
|
|
1152
1224
|
while (cursor) {
|
|
@@ -1199,23 +1271,24 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1199
1271
|
let skipped = 0;
|
|
1200
1272
|
let count = 0;
|
|
1201
1273
|
const dbTrx = this.toDbTrx(['certificates'], 'readonly', args.trx);
|
|
1274
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1202
1275
|
let cursor;
|
|
1203
1276
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.certificateId) {
|
|
1204
|
-
cursor = await dbTrx.objectStore('certificates').openCursor(args.partial.certificateId);
|
|
1277
|
+
cursor = await dbTrx.objectStore('certificates').openCursor(args.partial.certificateId, direction);
|
|
1205
1278
|
}
|
|
1206
1279
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.userId) !== undefined) {
|
|
1207
1280
|
if (((_d = args.partial) === null || _d === void 0 ? void 0 : _d.type) && ((_e = args.partial) === null || _e === void 0 ? void 0 : _e.certifier) && ((_f = args.partial) === null || _f === void 0 ? void 0 : _f.serialNumber)) {
|
|
1208
1281
|
cursor = await dbTrx
|
|
1209
1282
|
.objectStore('certificates')
|
|
1210
1283
|
.index('userId_type_certifier_serialNumber')
|
|
1211
|
-
.openCursor([args.partial.userId, args.partial.type, args.partial.certifier, args.partial.serialNumber]);
|
|
1284
|
+
.openCursor([args.partial.userId, args.partial.type, args.partial.certifier, args.partial.serialNumber], direction);
|
|
1212
1285
|
}
|
|
1213
1286
|
else {
|
|
1214
|
-
cursor = await dbTrx.objectStore('certificates').index('userId').openCursor(args.partial.userId);
|
|
1287
|
+
cursor = await dbTrx.objectStore('certificates').index('userId').openCursor(args.partial.userId, direction);
|
|
1215
1288
|
}
|
|
1216
1289
|
}
|
|
1217
1290
|
else {
|
|
1218
|
-
cursor = await dbTrx.objectStore('certificates').openCursor();
|
|
1291
|
+
cursor = await dbTrx.objectStore('certificates').openCursor(null, direction);
|
|
1219
1292
|
}
|
|
1220
1293
|
let firstTime = true;
|
|
1221
1294
|
while (cursor) {
|
|
@@ -1290,18 +1363,19 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1290
1363
|
let skipped = 0;
|
|
1291
1364
|
let count = 0;
|
|
1292
1365
|
const dbTrx = this.toDbTrx(['commissions'], 'readonly', args.trx);
|
|
1366
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1293
1367
|
let cursor;
|
|
1294
1368
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.commissionId) {
|
|
1295
|
-
cursor = await dbTrx.objectStore('commissions').openCursor(args.partial.commissionId);
|
|
1369
|
+
cursor = await dbTrx.objectStore('commissions').openCursor(args.partial.commissionId, direction);
|
|
1296
1370
|
}
|
|
1297
1371
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.userId) !== undefined) {
|
|
1298
|
-
cursor = await dbTrx.objectStore('commissions').index('userId').openCursor(args.partial.userId);
|
|
1372
|
+
cursor = await dbTrx.objectStore('commissions').index('userId').openCursor(args.partial.userId, direction);
|
|
1299
1373
|
}
|
|
1300
1374
|
else if (((_d = args.partial) === null || _d === void 0 ? void 0 : _d.transactionId) !== undefined) {
|
|
1301
|
-
cursor = await dbTrx.objectStore('commissions').index('transactionId').openCursor(args.partial.transactionId);
|
|
1375
|
+
cursor = await dbTrx.objectStore('commissions').index('transactionId').openCursor(args.partial.transactionId, direction);
|
|
1302
1376
|
}
|
|
1303
1377
|
else {
|
|
1304
|
-
cursor = await dbTrx.objectStore('commissions').openCursor();
|
|
1378
|
+
cursor = await dbTrx.objectStore('commissions').openCursor(null, direction);
|
|
1305
1379
|
}
|
|
1306
1380
|
let firstTime = true;
|
|
1307
1381
|
while (cursor) {
|
|
@@ -1356,12 +1430,13 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1356
1430
|
let skipped = 0;
|
|
1357
1431
|
let count = 0;
|
|
1358
1432
|
const dbTrx = this.toDbTrx(['monitor_events'], 'readonly', args.trx);
|
|
1433
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1359
1434
|
let cursor;
|
|
1360
1435
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.id) {
|
|
1361
|
-
cursor = await dbTrx.objectStore('monitor_events').openCursor(args.partial.id);
|
|
1436
|
+
cursor = await dbTrx.objectStore('monitor_events').openCursor(args.partial.id, direction);
|
|
1362
1437
|
}
|
|
1363
1438
|
else {
|
|
1364
|
-
cursor = await dbTrx.objectStore('monitor_events').openCursor();
|
|
1439
|
+
cursor = await dbTrx.objectStore('monitor_events').openCursor(null, direction);
|
|
1365
1440
|
}
|
|
1366
1441
|
let firstTime = true;
|
|
1367
1442
|
while (cursor) {
|
|
@@ -1410,23 +1485,24 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1410
1485
|
let skipped = 0;
|
|
1411
1486
|
let count = 0;
|
|
1412
1487
|
const dbTrx = this.toDbTrx(['output_baskets'], 'readonly', args.trx);
|
|
1488
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1413
1489
|
let cursor;
|
|
1414
1490
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.basketId) {
|
|
1415
|
-
cursor = await dbTrx.objectStore('output_baskets').openCursor(args.partial.basketId);
|
|
1491
|
+
cursor = await dbTrx.objectStore('output_baskets').openCursor(args.partial.basketId, direction);
|
|
1416
1492
|
}
|
|
1417
1493
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.userId) !== undefined) {
|
|
1418
1494
|
if (((_d = args.partial) === null || _d === void 0 ? void 0 : _d.name) !== undefined) {
|
|
1419
1495
|
cursor = await dbTrx
|
|
1420
1496
|
.objectStore('output_baskets')
|
|
1421
1497
|
.index('name_userId')
|
|
1422
|
-
.openCursor([args.partial.name, args.partial.userId]);
|
|
1498
|
+
.openCursor([args.partial.name, args.partial.userId], direction);
|
|
1423
1499
|
}
|
|
1424
1500
|
else {
|
|
1425
|
-
cursor = await dbTrx.objectStore('output_baskets').index('userId').openCursor(args.partial.userId);
|
|
1501
|
+
cursor = await dbTrx.objectStore('output_baskets').index('userId').openCursor(args.partial.userId, direction);
|
|
1426
1502
|
}
|
|
1427
1503
|
}
|
|
1428
1504
|
else {
|
|
1429
|
-
cursor = await dbTrx.objectStore('output_baskets').openCursor();
|
|
1505
|
+
cursor = await dbTrx.objectStore('output_baskets').openCursor(null, direction);
|
|
1430
1506
|
}
|
|
1431
1507
|
let firstTime = true;
|
|
1432
1508
|
while (cursor) {
|
|
@@ -1453,7 +1529,7 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1453
1529
|
r.numberOfDesiredUTXOs !== args.partial.numberOfDesiredUTXOs)
|
|
1454
1530
|
continue;
|
|
1455
1531
|
if (args.partial.minimumDesiredUTXOValue !== undefined &&
|
|
1456
|
-
r.
|
|
1532
|
+
r.minimumDesiredUTXOValue !== args.partial.minimumDesiredUTXOValue)
|
|
1457
1533
|
continue;
|
|
1458
1534
|
if (args.partial.isDeleted !== undefined && r.isDeleted !== args.partial.isDeleted)
|
|
1459
1535
|
continue;
|
|
@@ -1494,32 +1570,33 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1494
1570
|
stores.push('transactions');
|
|
1495
1571
|
}
|
|
1496
1572
|
const dbTrx = this.toDbTrx(stores, 'readonly', args.trx);
|
|
1573
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1497
1574
|
let cursor;
|
|
1498
1575
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.outputId) {
|
|
1499
|
-
cursor = await dbTrx.objectStore('outputs').openCursor(args.partial.outputId);
|
|
1576
|
+
cursor = await dbTrx.objectStore('outputs').openCursor(args.partial.outputId, direction);
|
|
1500
1577
|
}
|
|
1501
1578
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.userId) !== undefined) {
|
|
1502
1579
|
if (((_d = args.partial) === null || _d === void 0 ? void 0 : _d.transactionId) && ((_e = args.partial) === null || _e === void 0 ? void 0 : _e.vout) !== undefined) {
|
|
1503
1580
|
cursor = await dbTrx
|
|
1504
1581
|
.objectStore('outputs')
|
|
1505
1582
|
.index('transactionId_vout_userId')
|
|
1506
|
-
.openCursor([args.partial.transactionId, args.partial.vout, args.partial.userId]);
|
|
1583
|
+
.openCursor([args.partial.transactionId, args.partial.vout, args.partial.userId], direction);
|
|
1507
1584
|
}
|
|
1508
1585
|
else {
|
|
1509
|
-
cursor = await dbTrx.objectStore('outputs').index('userId').openCursor(args.partial.userId);
|
|
1586
|
+
cursor = await dbTrx.objectStore('outputs').index('userId').openCursor(args.partial.userId, direction);
|
|
1510
1587
|
}
|
|
1511
1588
|
}
|
|
1512
1589
|
else if (((_f = args.partial) === null || _f === void 0 ? void 0 : _f.transactionId) !== undefined) {
|
|
1513
|
-
cursor = await dbTrx.objectStore('outputs').index('transactionId').openCursor(args.partial.transactionId);
|
|
1590
|
+
cursor = await dbTrx.objectStore('outputs').index('transactionId').openCursor(args.partial.transactionId, direction);
|
|
1514
1591
|
}
|
|
1515
1592
|
else if (((_g = args.partial) === null || _g === void 0 ? void 0 : _g.basketId) !== undefined) {
|
|
1516
|
-
cursor = await dbTrx.objectStore('outputs').index('basketId').openCursor(args.partial.basketId);
|
|
1593
|
+
cursor = await dbTrx.objectStore('outputs').index('basketId').openCursor(args.partial.basketId, direction);
|
|
1517
1594
|
}
|
|
1518
1595
|
else if (((_h = args.partial) === null || _h === void 0 ? void 0 : _h.spentBy) !== undefined) {
|
|
1519
|
-
cursor = await dbTrx.objectStore('outputs').index('spentBy').openCursor(args.partial.spentBy);
|
|
1596
|
+
cursor = await dbTrx.objectStore('outputs').index('spentBy').openCursor(args.partial.spentBy, direction);
|
|
1520
1597
|
}
|
|
1521
1598
|
else {
|
|
1522
|
-
cursor = await dbTrx.objectStore('outputs').openCursor();
|
|
1599
|
+
cursor = await dbTrx.objectStore('outputs').openCursor(null, direction);
|
|
1523
1600
|
}
|
|
1524
1601
|
let firstTime = true;
|
|
1525
1602
|
while (cursor) {
|
|
@@ -1628,7 +1705,9 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1628
1705
|
}, tagIds, isQueryModeAll);
|
|
1629
1706
|
for (const o of results) {
|
|
1630
1707
|
if (!args.noScript) {
|
|
1631
|
-
|
|
1708
|
+
// Pass the transaction to avoid creating separate IDB operations
|
|
1709
|
+
// that would cause a passed transaction to auto-commit
|
|
1710
|
+
await this.validateOutputScript(o, args.trx);
|
|
1632
1711
|
}
|
|
1633
1712
|
else {
|
|
1634
1713
|
o.lockingScript = undefined;
|
|
@@ -1642,23 +1721,24 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1642
1721
|
let skipped = 0;
|
|
1643
1722
|
let count = 0;
|
|
1644
1723
|
const dbTrx = this.toDbTrx(['output_tags'], 'readonly', args.trx);
|
|
1724
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1645
1725
|
let cursor;
|
|
1646
1726
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.outputTagId) {
|
|
1647
|
-
cursor = await dbTrx.objectStore('output_tags').openCursor(args.partial.outputTagId);
|
|
1727
|
+
cursor = await dbTrx.objectStore('output_tags').openCursor(args.partial.outputTagId, direction);
|
|
1648
1728
|
}
|
|
1649
1729
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.userId) !== undefined) {
|
|
1650
1730
|
if (((_d = args.partial) === null || _d === void 0 ? void 0 : _d.tag) !== undefined) {
|
|
1651
1731
|
cursor = await dbTrx
|
|
1652
1732
|
.objectStore('output_tags')
|
|
1653
1733
|
.index('tag_userId')
|
|
1654
|
-
.openCursor([args.partial.tag, args.partial.userId]);
|
|
1734
|
+
.openCursor([args.partial.tag, args.partial.userId], direction);
|
|
1655
1735
|
}
|
|
1656
1736
|
else {
|
|
1657
|
-
cursor = await dbTrx.objectStore('output_tags').index('userId').openCursor(args.partial.userId);
|
|
1737
|
+
cursor = await dbTrx.objectStore('output_tags').index('userId').openCursor(args.partial.userId, direction);
|
|
1658
1738
|
}
|
|
1659
1739
|
}
|
|
1660
1740
|
else {
|
|
1661
|
-
cursor = await dbTrx.objectStore('output_tags').openCursor();
|
|
1741
|
+
cursor = await dbTrx.objectStore('output_tags').openCursor(null, direction);
|
|
1662
1742
|
}
|
|
1663
1743
|
let firstTime = true;
|
|
1664
1744
|
while (cursor) {
|
|
@@ -1711,21 +1791,22 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1711
1791
|
let skipped = 0;
|
|
1712
1792
|
let count = 0;
|
|
1713
1793
|
const dbTrx = this.toDbTrx(['sync_states'], 'readonly', args.trx);
|
|
1794
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1714
1795
|
let cursor;
|
|
1715
1796
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.syncStateId) {
|
|
1716
|
-
cursor = await dbTrx.objectStore('sync_states').openCursor(args.partial.syncStateId);
|
|
1797
|
+
cursor = await dbTrx.objectStore('sync_states').openCursor(args.partial.syncStateId, direction);
|
|
1717
1798
|
}
|
|
1718
1799
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.userId) !== undefined) {
|
|
1719
|
-
cursor = await dbTrx.objectStore('sync_states').index('userId').openCursor(args.partial.userId);
|
|
1800
|
+
cursor = await dbTrx.objectStore('sync_states').index('userId').openCursor(args.partial.userId, direction);
|
|
1720
1801
|
}
|
|
1721
1802
|
else if (((_d = args.partial) === null || _d === void 0 ? void 0 : _d.refNum) !== undefined) {
|
|
1722
|
-
cursor = await dbTrx.objectStore('sync_states').index('refNum').openCursor(args.partial.refNum);
|
|
1803
|
+
cursor = await dbTrx.objectStore('sync_states').index('refNum').openCursor(args.partial.refNum, direction);
|
|
1723
1804
|
}
|
|
1724
1805
|
else if (((_e = args.partial) === null || _e === void 0 ? void 0 : _e.status) !== undefined) {
|
|
1725
|
-
cursor = await dbTrx.objectStore('sync_states').index('status').openCursor(args.partial.status);
|
|
1806
|
+
cursor = await dbTrx.objectStore('sync_states').index('status').openCursor(args.partial.status, direction);
|
|
1726
1807
|
}
|
|
1727
1808
|
else {
|
|
1728
|
-
cursor = await dbTrx.objectStore('sync_states').openCursor();
|
|
1809
|
+
cursor = await dbTrx.objectStore('sync_states').openCursor(null, direction);
|
|
1729
1810
|
}
|
|
1730
1811
|
let firstTime = true;
|
|
1731
1812
|
while (cursor) {
|
|
@@ -1760,7 +1841,7 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1760
1841
|
continue;
|
|
1761
1842
|
if (args.partial.satoshis !== undefined && r.satoshis !== args.partial.satoshis)
|
|
1762
1843
|
continue;
|
|
1763
|
-
if (args.partial.errorLocal && r.
|
|
1844
|
+
if (args.partial.errorLocal && r.errorLocal !== args.partial.errorLocal)
|
|
1764
1845
|
continue;
|
|
1765
1846
|
if (args.partial.errorOther && r.errorOther !== args.partial.errorOther)
|
|
1766
1847
|
continue;
|
|
@@ -1798,32 +1879,33 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1798
1879
|
stores.push('tx_labels_map');
|
|
1799
1880
|
}
|
|
1800
1881
|
const dbTrx = this.toDbTrx(stores, 'readonly', args.trx);
|
|
1882
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1801
1883
|
let cursor;
|
|
1802
1884
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.transactionId) {
|
|
1803
|
-
cursor = await dbTrx.objectStore('transactions').openCursor(args.partial.transactionId);
|
|
1885
|
+
cursor = await dbTrx.objectStore('transactions').openCursor(args.partial.transactionId, direction);
|
|
1804
1886
|
}
|
|
1805
1887
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.userId) !== undefined) {
|
|
1806
1888
|
if (((_d = args.partial) === null || _d === void 0 ? void 0 : _d.status) !== undefined) {
|
|
1807
1889
|
cursor = await dbTrx
|
|
1808
1890
|
.objectStore('transactions')
|
|
1809
1891
|
.index('status_userId')
|
|
1810
|
-
.openCursor([args.partial.status, args.partial.userId]);
|
|
1892
|
+
.openCursor([args.partial.status, args.partial.userId], direction);
|
|
1811
1893
|
}
|
|
1812
1894
|
else {
|
|
1813
|
-
cursor = await dbTrx.objectStore('transactions').index('userId').openCursor(args.partial.userId);
|
|
1895
|
+
cursor = await dbTrx.objectStore('transactions').index('userId').openCursor(args.partial.userId, direction);
|
|
1814
1896
|
}
|
|
1815
1897
|
}
|
|
1816
1898
|
else if (((_e = args.partial) === null || _e === void 0 ? void 0 : _e.status) !== undefined) {
|
|
1817
|
-
cursor = await dbTrx.objectStore('transactions').index('status').openCursor(args.partial.status);
|
|
1899
|
+
cursor = await dbTrx.objectStore('transactions').index('status').openCursor(args.partial.status, direction);
|
|
1818
1900
|
}
|
|
1819
1901
|
else if (((_f = args.partial) === null || _f === void 0 ? void 0 : _f.provenTxId) !== undefined) {
|
|
1820
|
-
cursor = await dbTrx.objectStore('transactions').index('provenTxId').openCursor(args.partial.provenTxId);
|
|
1902
|
+
cursor = await dbTrx.objectStore('transactions').index('provenTxId').openCursor(args.partial.provenTxId, direction);
|
|
1821
1903
|
}
|
|
1822
1904
|
else if (((_g = args.partial) === null || _g === void 0 ? void 0 : _g.reference) !== undefined) {
|
|
1823
|
-
cursor = await dbTrx.objectStore('transactions').index('reference').openCursor(args.partial.reference);
|
|
1905
|
+
cursor = await dbTrx.objectStore('transactions').index('reference').openCursor(args.partial.reference, direction);
|
|
1824
1906
|
}
|
|
1825
1907
|
else {
|
|
1826
|
-
cursor = await dbTrx.objectStore('transactions').openCursor();
|
|
1908
|
+
cursor = await dbTrx.objectStore('transactions').openCursor(null, direction);
|
|
1827
1909
|
}
|
|
1828
1910
|
let firstTime = true;
|
|
1829
1911
|
while (cursor) {
|
|
@@ -1917,23 +1999,24 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1917
1999
|
let skipped = 0;
|
|
1918
2000
|
let count = 0;
|
|
1919
2001
|
const dbTrx = this.toDbTrx(['tx_labels'], 'readonly', args.trx);
|
|
2002
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
1920
2003
|
let cursor;
|
|
1921
2004
|
if ((_b = args.partial) === null || _b === void 0 ? void 0 : _b.txLabelId) {
|
|
1922
|
-
cursor = await dbTrx.objectStore('tx_labels').openCursor(args.partial.txLabelId);
|
|
2005
|
+
cursor = await dbTrx.objectStore('tx_labels').openCursor(args.partial.txLabelId, direction);
|
|
1923
2006
|
}
|
|
1924
2007
|
else if (((_c = args.partial) === null || _c === void 0 ? void 0 : _c.userId) !== undefined) {
|
|
1925
2008
|
if (((_d = args.partial) === null || _d === void 0 ? void 0 : _d.label) !== undefined) {
|
|
1926
2009
|
cursor = await dbTrx
|
|
1927
2010
|
.objectStore('tx_labels')
|
|
1928
2011
|
.index('label_userId')
|
|
1929
|
-
.openCursor([args.partial.label, args.partial.userId]);
|
|
2012
|
+
.openCursor([args.partial.label, args.partial.userId], direction);
|
|
1930
2013
|
}
|
|
1931
2014
|
else {
|
|
1932
|
-
cursor = await dbTrx.objectStore('tx_labels').index('userId').openCursor(args.partial.userId);
|
|
2015
|
+
cursor = await dbTrx.objectStore('tx_labels').index('userId').openCursor(args.partial.userId, direction);
|
|
1933
2016
|
}
|
|
1934
2017
|
}
|
|
1935
2018
|
else {
|
|
1936
|
-
cursor = await dbTrx.objectStore('tx_labels').openCursor();
|
|
2019
|
+
cursor = await dbTrx.objectStore('tx_labels').openCursor(null, direction);
|
|
1937
2020
|
}
|
|
1938
2021
|
let firstTime = true;
|
|
1939
2022
|
while (cursor) {
|
|
@@ -1984,7 +2067,8 @@ class StorageIdb extends StorageProvider_1.StorageProvider {
|
|
|
1984
2067
|
let skipped = 0;
|
|
1985
2068
|
let count = 0;
|
|
1986
2069
|
const dbTrx = this.toDbTrx(['users'], 'readonly', args.trx);
|
|
1987
|
-
|
|
2070
|
+
const direction = args.orderDescending ? 'prev' : 'next';
|
|
2071
|
+
let cursor = await dbTrx.objectStore('users').openCursor(null, direction);
|
|
1988
2072
|
let firstTime = true;
|
|
1989
2073
|
while (cursor) {
|
|
1990
2074
|
if (!firstTime)
|