mainnet-js 3.1.5 → 3.1.6

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.
@@ -114,24 +114,21 @@ describe("HDWallet", () => {
114
114
  cashaddr: hdWallet.getDepositAddress(0),
115
115
  value: 100000n,
116
116
  });
117
- while (hdWallet.depositIndex < 1)
118
- await new Promise((r) => setTimeout(r, 50));
117
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
119
118
  expect(hdWallet.depositIndex).toBe(1);
120
119
 
121
120
  await fundingWallet.send({
122
121
  cashaddr: hdWallet.getDepositAddress(1),
123
122
  value: 100000n,
124
123
  });
125
- while (hdWallet.depositIndex < 2)
126
- await new Promise((r) => setTimeout(r, 50));
124
+ await hdWallet.waitForUpdate({ depositIndex: 2 });
127
125
  expect(hdWallet.depositIndex).toBe(2);
128
126
 
129
127
  await fundingWallet.send({
130
128
  cashaddr: hdWallet.getDepositAddress(4),
131
129
  value: 100000n,
132
130
  });
133
- while (hdWallet.depositIndex < 5)
134
- await new Promise((r) => setTimeout(r, 50));
131
+ await hdWallet.waitForUpdate({ depositIndex: 5 });
135
132
  expect(hdWallet.depositIndex).toBe(5);
136
133
 
137
134
  // beyond gap size, should not update index
@@ -163,8 +160,7 @@ describe("HDWallet", () => {
163
160
  { cashaddr: addr20, value: 10000n },
164
161
  ]);
165
162
  // Wait for seedWallet to see both transactions via electrum
166
- while (seedWallet.depositIndex < 21)
167
- await new Promise((r) => setTimeout(r, 50));
163
+ await seedWallet.waitForUpdate({ depositIndex: 21 });
168
164
 
169
165
  // Restore wallet from same seed, starting from index 0
170
166
  const restoredWallet = await RegTestHDWallet.fromSeed(
@@ -191,8 +187,7 @@ describe("HDWallet", () => {
191
187
  cashaddr: hdWallet.getDepositAddress(0),
192
188
  value: 100000n,
193
189
  });
194
- while (hdWallet.depositIndex < 1)
195
- await new Promise((r) => setTimeout(r, 50));
190
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
196
191
  expect(hdWallet.depositIndex).toBe(1);
197
192
  expect(hdWallet.changeIndex).toBe(0);
198
193
 
@@ -201,9 +196,7 @@ describe("HDWallet", () => {
201
196
  cashaddr: bob.getDepositAddress(),
202
197
  value: 50000n,
203
198
  });
204
- while (hdWallet.changeIndex < 1) {
205
- await new Promise((r) => setTimeout(r, 50));
206
- }
199
+ await hdWallet.waitForUpdate({ changeIndex: 1 });
207
200
  expect(hdWallet.changeIndex).toBe(1);
208
201
 
209
202
  // fund and spend again, change goes to change address 1
@@ -211,15 +204,12 @@ describe("HDWallet", () => {
211
204
  cashaddr: hdWallet.getDepositAddress(),
212
205
  value: 100000n,
213
206
  });
214
- while (hdWallet.depositIndex < 2)
215
- await new Promise((r) => setTimeout(r, 50));
207
+ await hdWallet.waitForUpdate({ depositIndex: 2 });
216
208
  await hdWallet.send({
217
209
  cashaddr: bob.getDepositAddress(),
218
210
  value: 50000n,
219
211
  });
220
- while (hdWallet.changeIndex < 2) {
221
- await new Promise((r) => setTimeout(r, 50));
222
- }
212
+ await hdWallet.waitForUpdate({ changeIndex: 2 });
223
213
  expect(hdWallet.changeIndex).toBe(2);
224
214
 
225
215
  // Restore wallet from same seed and verify depositIndex is correct
@@ -261,8 +251,7 @@ describe("HDWallet", () => {
261
251
  cashaddr: depositAddress,
262
252
  value: 100000n,
263
253
  });
264
- while (hdWallet.depositIndex < 1)
265
- await new Promise((r) => setTimeout(r, 50));
254
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
266
255
 
267
256
  expect(await hdWallet.getBalance()).toBe(100000n);
268
257
 
@@ -274,8 +263,7 @@ describe("HDWallet", () => {
274
263
  cashaddr: depositAddress2,
275
264
  value: 100000n,
276
265
  });
277
- while (hdWallet.depositIndex < 2)
278
- await new Promise((r) => setTimeout(r, 50));
266
+ await hdWallet.waitForUpdate({ depositIndex: 2 });
279
267
 
280
268
  expect(await hdWallet.getBalance()).toBe(200000n);
281
269
 
@@ -307,8 +295,7 @@ describe("HDWallet", () => {
307
295
  cashaddr: bob.getDepositAddress(),
308
296
  value: 150000n,
309
297
  });
310
- while (hdWallet.changeIndex < 1)
311
- await new Promise((r) => setTimeout(r, 50));
298
+ await hdWallet.waitForUpdate({ changeIndex: 1 });
312
299
 
313
300
  expect(
314
301
  await (
@@ -367,8 +354,7 @@ describe("HDWallet", () => {
367
354
  cashaddr: depositAddress,
368
355
  value: 100000n,
369
356
  });
370
- while (hdWallet.depositIndex < 1)
371
- await new Promise((r) => setTimeout(r, 50));
357
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
372
358
 
373
359
  expect(await hdWallet.getBalance()).toBe(100000n);
374
360
 
@@ -462,8 +448,7 @@ describe("HDWallet", () => {
462
448
  cashaddr: hdWallet.getDepositAddress(0),
463
449
  value: 100000n,
464
450
  });
465
- while (hdWallet.depositIndex < 1)
466
- await new Promise((r) => setTimeout(r, 50));
451
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
467
452
 
468
453
  expect(
469
454
  hdWallet.walletCache.get(hdWallet.getDepositAddress(0))?.status
@@ -514,8 +499,7 @@ describe("HDWallet", () => {
514
499
  cashaddr: hdWallet.getDepositAddress(0),
515
500
  value: 100000n,
516
501
  });
517
- while (hdWallet.depositIndex < 1)
518
- await new Promise((r) => setTimeout(r, 50));
502
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
519
503
 
520
504
  // rawHistory should now have one entry
521
505
  expect(
@@ -557,15 +541,13 @@ describe("HDWallet", () => {
557
541
  cashaddr: hdWallet.getDepositAddress(0),
558
542
  value: 100000n,
559
543
  });
560
- while (hdWallet.depositIndex < 1)
561
- await new Promise((r) => setTimeout(r, 50));
544
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
562
545
 
563
546
  await fundingWallet.send({
564
547
  cashaddr: hdWallet.getDepositAddress(1),
565
548
  value: 100000n,
566
549
  });
567
- while (hdWallet.depositIndex < 2)
568
- await new Promise((r) => setTimeout(r, 50));
550
+ await hdWallet.waitForUpdate({ depositIndex: 2 });
569
551
 
570
552
  // Check depositRawHistory arrays are populated
571
553
  expect(hdWallet.depositRawHistory[0].length).toBe(1);
@@ -591,8 +573,7 @@ describe("HDWallet", () => {
591
573
  cashaddr: hdWallet.getDepositAddress(0),
592
574
  value: 100000n,
593
575
  });
594
- while (hdWallet.depositIndex < 1)
595
- await new Promise((r) => setTimeout(r, 50));
576
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
596
577
 
597
578
  const history = await hdWallet.getHistory({ unit: "sat" });
598
579
  expect(history.length).toBe(1);
@@ -614,8 +595,7 @@ describe("HDWallet", () => {
614
595
  cashaddr: hdWallet.getDepositAddress(0),
615
596
  value: 50000n,
616
597
  });
617
- while (hdWallet.depositIndex < 1)
618
- await new Promise((r) => setTimeout(r, 50));
598
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
619
599
 
620
600
  // Check rawHistory is populated
621
601
  const cacheEntry1 = hdWallet.walletCache.get(hdWallet.getDepositAddress(0));
@@ -670,6 +650,33 @@ describe("HDWallet", () => {
670
650
  expect((hdWallet as any).walletWatchCallbacks.length).toBe(0);
671
651
  });
672
652
 
653
+ it("waitForUpdate resolves via timeout when depositIndex target is not reached", async () => {
654
+ const fundingWallet = await RegTestWallet.fromId(
655
+ "wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
656
+ );
657
+ const hdWallet = await RegTestHDWallet.newRandom();
658
+ expect(hdWallet.depositIndex).toBe(0);
659
+
660
+ // No transaction sent — idle timer should resolve without hanging
661
+ await hdWallet.waitForUpdate({ depositIndex: 1 });
662
+
663
+ // depositIndex is still 0 because no funds arrived
664
+ expect(hdWallet.depositIndex).toBe(0);
665
+
666
+ // No leftover watchers
667
+ expect((hdWallet as any).walletWatchCallbacks.length).toBe(0);
668
+
669
+ // Now send a real transaction — waitForUpdate should resolve once index advances
670
+ await fundingWallet.send({
671
+ cashaddr: hdWallet.getDepositAddress(0),
672
+ value: 100000n,
673
+ });
674
+ await hdWallet.waitForUpdate();
675
+
676
+ expect(hdWallet.depositIndex).toBe(1);
677
+ expect((hdWallet as any).walletWatchCallbacks.length).toBe(0);
678
+ });
679
+
673
680
  it("watchWallet supports multiple watchers", async () => {
674
681
  const hdWallet = await RegTestHDWallet.newRandom();
675
682
 
@@ -720,7 +727,7 @@ describe("HDWallet", () => {
720
727
  cashaddr: alice.getDepositAddress(),
721
728
  value: 1000000n,
722
729
  });
723
- while (alice.depositIndex < 1) await new Promise((r) => setTimeout(r, 50));
730
+ await alice.waitForUpdate({ depositIndex: 1 });
724
731
 
725
732
  const genesisResponse = await alice.tokenGenesis({
726
733
  cashaddr: alice.getDepositAddress(1),
@@ -805,7 +812,7 @@ describe("HDWallet", () => {
805
812
  cashaddr: alice.getDepositAddress(),
806
813
  value: 1000000n,
807
814
  });
808
- while (alice.depositIndex < 1) await new Promise((r) => setTimeout(r, 50));
815
+ await alice.waitForUpdate({ depositIndex: 1 });
809
816
 
810
817
  const genesisResponse = await alice.tokenGenesis({
811
818
  amount: 100n,
@@ -1043,8 +1050,7 @@ describe("HDWallet", () => {
1043
1050
  });
1044
1051
 
1045
1052
  // Wait for the subscription callback to fire and gap extension to complete
1046
- while (hdWallet.depositIndex < edgeIndex + 1)
1047
- await new Promise((r) => setTimeout(r, 50));
1053
+ await hdWallet.waitForUpdate({ depositIndex: edgeIndex + 1 });
1048
1054
  await delay(1000);
1049
1055
 
1050
1056
  // depositIndex should have advanced
@@ -1066,8 +1072,7 @@ describe("HDWallet", () => {
1066
1072
  cashaddr: hdWallet.getDepositAddress(newEdge),
1067
1073
  value: 10000n,
1068
1074
  });
1069
- while (hdWallet.depositIndex < newEdge + 1)
1070
- await new Promise((r) => setTimeout(r, 50));
1075
+ await hdWallet.waitForUpdate({ depositIndex: newEdge + 1 });
1071
1076
  await delay(1000);
1072
1077
 
1073
1078
  expect(hdWallet.depositIndex).toBe(newEdge + 1);
@@ -499,6 +499,73 @@ export class HDWallet extends BaseWallet {
499
499
  };
500
500
  }
501
501
 
502
+ /**
503
+ * Wait for the wallet to reach a target depositIndex and/or changeIndex,
504
+ * resolving once the condition is met or after an idle timeout with no
505
+ * status changes.
506
+ */
507
+ public async waitForUpdate(
508
+ options: {
509
+ depositIndex?: number;
510
+ changeIndex?: number;
511
+ timeout?: number;
512
+ } = {}
513
+ ): Promise<void> {
514
+ const timeout = options.timeout ?? 100;
515
+
516
+ const isSatisfied = () => {
517
+ if (
518
+ options.depositIndex !== undefined &&
519
+ this.depositIndex < options.depositIndex
520
+ )
521
+ return false;
522
+ if (
523
+ options.changeIndex !== undefined &&
524
+ this.changeIndex < options.changeIndex
525
+ )
526
+ return false;
527
+ return true;
528
+ };
529
+
530
+ if (isSatisfied()) return;
531
+
532
+ return new Promise(async (resolve) => {
533
+ let timer: ReturnType<typeof setTimeout>;
534
+ let resolved = false;
535
+ let watchCancel: CancelFn;
536
+
537
+ const done = async () => {
538
+ if (resolved) return;
539
+ resolved = true;
540
+ clearTimeout(timer);
541
+ await watchCancel?.();
542
+ resolve();
543
+ };
544
+
545
+ const resetTimer = () => {
546
+ clearTimeout(timer);
547
+ timer = setTimeout(done, timeout);
548
+ };
549
+
550
+ // Uses default 100ms debounce — callback only fires after 100ms of
551
+ // quiet, meaning the cascade has settled before we check the condition.
552
+ watchCancel = await this.watchStatus(async () => {
553
+ if (isSatisfied()) {
554
+ await done();
555
+ } else {
556
+ resetTimer(); // cascade settled but target not met — wait for more activity
557
+ }
558
+ });
559
+
560
+ // Re-check + start initial idle timer after subscription
561
+ if (isSatisfied()) {
562
+ await done();
563
+ } else {
564
+ resetTimer();
565
+ }
566
+ });
567
+ }
568
+
502
569
  /**
503
570
  * Watch wallet for new transactions (HD wallet override)
504
571
  *
@@ -1187,5 +1187,3 @@ describe(`Wallet extrema behavior regression testing`, () => {
1187
1187
  ).resolves.not.toThrow();
1188
1188
  });
1189
1189
  });
1190
-
1191
-
package/src/wallet/Wif.ts CHANGED
@@ -225,7 +225,10 @@ export class Wallet extends WatchWallet {
225
225
 
226
226
  if (this.privateKey) {
227
227
  // @ts-ignore
228
- this.walletCache = new Map<string, { privateKey: Uint8Array }>().set(this.cashaddr, { privateKey: this.privateKey });
228
+ this.walletCache = new Map<string, { privateKey: Uint8Array }>().set(
229
+ this.cashaddr,
230
+ { privateKey: this.privateKey }
231
+ );
229
232
  }
230
233
 
231
234
  return this;