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.
- package/dist/index.html +1 -1
- package/dist/{mainnet-3.1.5.js → mainnet-3.1.6.js} +2 -2
- package/dist/module/wallet/Base.d.ts +9 -0
- package/dist/module/wallet/Base.d.ts.map +1 -1
- package/dist/module/wallet/Base.js +5 -0
- package/dist/module/wallet/Base.js.map +1 -1
- package/dist/module/wallet/HDWallet.d.ts +10 -0
- package/dist/module/wallet/HDWallet.d.ts.map +1 -1
- package/dist/module/wallet/HDWallet.js +53 -0
- package/dist/module/wallet/HDWallet.js.map +1 -1
- package/dist/module/wallet/Wif.d.ts.map +1 -1
- package/dist/module/wallet/Wif.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/wallet/Base.ts +12 -0
- package/src/wallet/HDWallet.test.ts +49 -44
- package/src/wallet/HDWallet.ts +67 -0
- package/src/wallet/Wif.test.ts +0 -2
- package/src/wallet/Wif.ts +4 -1
|
@@ -114,24 +114,21 @@ describe("HDWallet", () => {
|
|
|
114
114
|
cashaddr: hdWallet.getDepositAddress(0),
|
|
115
115
|
value: 100000n,
|
|
116
116
|
});
|
|
117
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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);
|
package/src/wallet/HDWallet.ts
CHANGED
|
@@ -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
|
*
|
package/src/wallet/Wif.test.ts
CHANGED
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(
|
|
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;
|