mainnet-js 3.1.7 → 4.0.0-next.10
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/module/cache/IndexedDbCache.d.ts +1 -1
- package/dist/module/cache/IndexedDbCache.d.ts.map +1 -1
- package/dist/module/cache/MemoryCache.d.ts +1 -1
- package/dist/module/cache/MemoryCache.d.ts.map +1 -1
- package/dist/module/cache/WebStorageCache.d.ts +1 -1
- package/dist/module/cache/WebStorageCache.d.ts.map +1 -1
- package/dist/module/cache/walletCache.d.ts +16 -6
- package/dist/module/cache/walletCache.d.ts.map +1 -1
- package/dist/module/cache/walletCache.js +92 -34
- package/dist/module/cache/walletCache.js.map +1 -1
- package/dist/module/cli.js +1 -2
- package/dist/module/cli.js.map +1 -1
- package/dist/module/db/index.d.ts +1 -1
- package/dist/module/db/index.d.ts.map +1 -1
- package/dist/module/db/index.js +1 -1
- package/dist/module/db/index.js.map +1 -1
- package/dist/module/enum.d.ts +1 -1
- package/dist/module/enum.d.ts.map +1 -1
- package/dist/module/history/getHistory.d.ts +1 -1
- package/dist/module/history/getHistory.d.ts.map +1 -1
- package/dist/module/history/getHistory.js +3 -3
- package/dist/module/history/getHistory.js.map +1 -1
- package/dist/module/index.d.ts +25 -22
- package/dist/module/index.d.ts.map +1 -1
- package/dist/module/index.js +33 -26
- package/dist/module/index.js.map +1 -1
- package/dist/module/interface.d.ts +12 -2
- package/dist/module/interface.d.ts.map +1 -1
- package/dist/module/interface.js.map +1 -1
- package/dist/module/libauth.d.ts +1 -1
- package/dist/module/libauth.d.ts.map +1 -1
- package/dist/module/libauth.js +1 -1
- package/dist/module/libauth.js.map +1 -1
- package/dist/module/mine/mine.d.ts +2 -7
- package/dist/module/mine/mine.d.ts.map +1 -1
- package/dist/module/mine/mine.js +6 -27
- package/dist/module/mine/mine.js.map +1 -1
- package/dist/module/network/Connection.d.ts +1 -12
- package/dist/module/network/Connection.d.ts.map +1 -1
- package/dist/module/network/Connection.js +24 -33
- package/dist/module/network/Connection.js.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.d.ts +16 -17
- package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.js +91 -93
- package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
- package/dist/module/network/MockNetworkProvider.d.ts +28 -0
- package/dist/module/network/MockNetworkProvider.d.ts.map +1 -0
- package/dist/module/network/MockNetworkProvider.js +74 -0
- package/dist/module/network/MockNetworkProvider.js.map +1 -0
- package/dist/module/network/NetworkProvider.d.ts +9 -2
- package/dist/module/network/NetworkProvider.d.ts.map +1 -1
- package/dist/module/network/configuration.d.ts +2 -4
- package/dist/module/network/configuration.d.ts.map +1 -1
- package/dist/module/network/configuration.js +25 -50
- package/dist/module/network/configuration.js.map +1 -1
- package/dist/module/network/constant.d.ts +7 -7
- package/dist/module/network/constant.d.ts.map +1 -1
- package/dist/module/network/constant.js +21 -24
- package/dist/module/network/constant.js.map +1 -1
- package/dist/module/network/default.d.ts +5 -3
- package/dist/module/network/default.d.ts.map +1 -1
- package/dist/module/network/default.js +29 -51
- package/dist/module/network/default.js.map +1 -1
- package/dist/module/network/index.d.ts +4 -4
- package/dist/module/network/index.d.ts.map +1 -1
- package/dist/module/network/index.js +2 -2
- package/dist/module/network/index.js.map +1 -1
- package/dist/module/network/interface.d.ts +0 -6
- package/dist/module/network/interface.d.ts.map +1 -1
- package/dist/module/rate/ExchangeRate.d.ts +1 -1
- package/dist/module/rate/ExchangeRate.d.ts.map +1 -1
- package/dist/module/rate/ExchangeRate.js +13 -7
- package/dist/module/rate/ExchangeRate.js.map +1 -1
- package/dist/module/transaction/Wif.d.ts +3 -3
- package/dist/module/transaction/Wif.d.ts.map +1 -1
- package/dist/module/transaction/Wif.js +4 -4
- package/dist/module/transaction/Wif.js.map +1 -1
- package/dist/module/transaction/allocateFee.d.ts +1 -1
- package/dist/module/transaction/allocateFee.d.ts.map +1 -1
- package/dist/module/transaction/allocateFee.js +2 -2
- package/dist/module/transaction/allocateFee.js.map +1 -1
- package/dist/module/util/deriveCashaddr.js.map +1 -1
- package/dist/module/util/deriveNetwork.js +1 -1
- package/dist/module/util/deriveNetwork.js.map +1 -1
- package/dist/module/util/getAddrsByXpubKey.js +1 -1
- package/dist/module/util/getAddrsByXpubKey.js.map +1 -1
- package/dist/module/util/getXPubKey.js +1 -1
- package/dist/module/util/getXPubKey.js.map +1 -1
- package/dist/module/util/hd.d.ts +2 -0
- package/dist/module/util/hd.d.ts.map +1 -1
- package/dist/module/util/hd.js +41 -0
- package/dist/module/util/hd.js.map +1 -1
- package/dist/module/util/index.d.ts +7 -9
- package/dist/module/util/index.d.ts.map +1 -1
- package/dist/module/util/index.js +7 -9
- package/dist/module/util/index.js.map +1 -1
- package/dist/module/util/transaction.js +1 -1
- package/dist/module/util/transaction.js.map +1 -1
- package/dist/module/wallet/Base.d.ts +13 -9
- package/dist/module/wallet/Base.d.ts.map +1 -1
- package/dist/module/wallet/Base.js +54 -58
- package/dist/module/wallet/Base.js.map +1 -1
- package/dist/module/wallet/HDWallet.d.ts.map +1 -1
- package/dist/module/wallet/HDWallet.js +19 -38
- package/dist/module/wallet/HDWallet.js.map +1 -1
- package/dist/module/wallet/Util.d.ts +4 -22
- package/dist/module/wallet/Util.d.ts.map +1 -1
- package/dist/module/wallet/Util.js +75 -102
- package/dist/module/wallet/Util.js.map +1 -1
- package/dist/module/wallet/Watch.d.ts +24 -5
- package/dist/module/wallet/Watch.d.ts.map +1 -1
- package/dist/module/wallet/Watch.js +141 -17
- package/dist/module/wallet/Watch.js.map +1 -1
- package/dist/module/wallet/Wif.d.ts +2 -6
- package/dist/module/wallet/Wif.d.ts.map +1 -1
- package/dist/module/wallet/Wif.js +3 -69
- package/dist/module/wallet/Wif.js.map +1 -1
- package/dist/module/wallet/createWallet.d.ts +1 -1
- package/dist/module/wallet/createWallet.d.ts.map +1 -1
- package/dist/module/wallet/createWallet.js +2 -1
- package/dist/module/wallet/createWallet.js.map +1 -1
- package/dist/module/wallet/interface.d.ts +3 -2
- package/dist/module/wallet/interface.d.ts.map +1 -1
- package/dist/module/wallet/model.d.ts +2 -1
- package/dist/module/wallet/model.d.ts.map +1 -1
- package/dist/module/wallet/model.js +1 -1
- package/dist/module/wallet/model.js.map +1 -1
- package/package.json +17 -29
- package/dist/index.html +0 -9
- package/dist/mainnet-3.1.7.js +0 -2066
- package/dist/module/network/util.d.ts +0 -3
- package/dist/module/network/util.d.ts.map +0 -1
- package/dist/module/network/util.js +0 -27
- package/dist/module/network/util.js.map +0 -1
- package/dist/module/test/expect.d.ts +0 -12
- package/dist/module/test/expect.d.ts.map +0 -1
- package/dist/module/test/expect.js +0 -47
- package/dist/module/test/expect.js.map +0 -1
- package/dist/module/test/fetch.d.ts +0 -3
- package/dist/module/test/fetch.d.ts.map +0 -1
- package/dist/module/test/fetch.js +0 -32
- package/dist/module/test/fetch.js.map +0 -1
- package/dist/module/util/randomBytes.d.ts +0 -2
- package/dist/module/util/randomBytes.d.ts.map +0 -1
- package/dist/module/util/randomBytes.js +0 -13
- package/dist/module/util/randomBytes.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/cache/IndexedDbCache.test.ts +0 -15
- package/src/cache/IndexedDbCache.ts +0 -172
- package/src/cache/MemoryCache.test.ts +0 -15
- package/src/cache/MemoryCache.ts +0 -32
- package/src/cache/WebStorageCache.test.ts +0 -15
- package/src/cache/WebStorageCache.ts +0 -38
- package/src/cache/index.ts +0 -2
- package/src/cache/interface.ts +0 -9
- package/src/cache/walletCache.ts +0 -254
- package/src/chain.ts +0 -3
- package/src/cli.ts +0 -32
- package/src/config.ts +0 -23
- package/src/constant.ts +0 -27
- package/src/db/ExchangeRateProvider.ts +0 -28
- package/src/db/StorageProvider.ts +0 -64
- package/src/db/index.ts +0 -2
- package/src/db/interface.ts +0 -11
- package/src/enum.ts +0 -34
- package/src/history/getHistory.test.ts +0 -290
- package/src/history/getHistory.ts +0 -411
- package/src/history/interface.ts +0 -24
- package/src/index.ts +0 -48
- package/src/interface.ts +0 -72
- package/src/libauth.ts +0 -11
- package/src/message/index.ts +0 -2
- package/src/message/interface.ts +0 -40
- package/src/message/signed.test.ts +0 -309
- package/src/message/signed.ts +0 -201
- package/src/mine/index.ts +0 -1
- package/src/mine/mine.test.ts +0 -10
- package/src/mine/mine.ts +0 -42
- package/src/network/Connection.test.ts +0 -51
- package/src/network/Connection.ts +0 -73
- package/src/network/ElectrumNetworkProvider.ts +0 -657
- package/src/network/NetworkProvider.ts +0 -180
- package/src/network/Rpc.test.ts +0 -130
- package/src/network/configuration.test.ts +0 -59
- package/src/network/configuration.ts +0 -72
- package/src/network/constant.ts +0 -43
- package/src/network/default.ts +0 -120
- package/src/network/electrum.test.ts +0 -28
- package/src/network/getRelayFeeCache.test.ts +0 -15
- package/src/network/getRelayFeeCache.ts +0 -23
- package/src/network/index.ts +0 -14
- package/src/network/interface.ts +0 -80
- package/src/network/util.test.ts +0 -24
- package/src/network/util.ts +0 -30
- package/src/rate/ExchangeRate.test.headless.js +0 -35
- package/src/rate/ExchangeRate.test.ts +0 -51
- package/src/rate/ExchangeRate.ts +0 -142
- package/src/test/expect.ts +0 -59
- package/src/test/fetch.ts +0 -39
- package/src/test/json.test.ts +0 -13
- package/src/transaction/Wif.ts +0 -680
- package/src/transaction/allocateFee.test.ts +0 -298
- package/src/transaction/allocateFee.ts +0 -149
- package/src/util/amountInSatoshi.test.ts +0 -27
- package/src/util/amountInSatoshi.ts +0 -33
- package/src/util/asSendRequestObject.ts +0 -81
- package/src/util/base64.test.ts +0 -39
- package/src/util/base64.ts +0 -12
- package/src/util/browserNotSupported.ts +0 -7
- package/src/util/checkForEmptySeed.ts +0 -9
- package/src/util/checkUtxos.ts +0 -29
- package/src/util/checkWifNetwork.ts +0 -24
- package/src/util/convert.test.ts +0 -46
- package/src/util/convert.ts +0 -50
- package/src/util/delay.ts +0 -3
- package/src/util/deriveCashaddr.test.ts +0 -164
- package/src/util/deriveCashaddr.ts +0 -143
- package/src/util/deriveLockscript.ts +0 -16
- package/src/util/deriveNetwork.ts +0 -19
- package/src/util/derivePublicKeyHash.test.ts +0 -55
- package/src/util/derivePublicKeyHash.ts +0 -64
- package/src/util/floor.test.ts +0 -21
- package/src/util/floor.ts +0 -4
- package/src/util/getAddrsByXpubKey.test.ts +0 -115
- package/src/util/getAddrsByXpubKey.ts +0 -86
- package/src/util/getRuntimePlatform.test.headless.js +0 -40
- package/src/util/getRuntimePlatform.test.ts +0 -5
- package/src/util/getRuntimePlatform.ts +0 -31
- package/src/util/getUsdRate.ts +0 -5
- package/src/util/getXPubKey.ts +0 -39
- package/src/util/hash160.test.ts +0 -18
- package/src/util/hash160.ts +0 -12
- package/src/util/hd.ts +0 -16
- package/src/util/header.test.ts +0 -34
- package/src/util/header.ts +0 -26
- package/src/util/index.ts +0 -33
- package/src/util/randomBytes.ts +0 -13
- package/src/util/randomInt.test.ts +0 -15
- package/src/util/randomInt.ts +0 -4
- package/src/util/sanitizeAddress.ts +0 -10
- package/src/util/sanitizeUnit.ts +0 -11
- package/src/util/satoshiToAmount.test.ts +0 -6
- package/src/util/satoshiToAmount.ts +0 -33
- package/src/util/sumSendRequestAmounts.ts +0 -34
- package/src/util/sumUtxoValue.ts +0 -27
- package/src/util/transaction.ts +0 -10
- package/src/wallet/Base.ts +0 -1563
- package/src/wallet/Cashtokens.test.headless.js +0 -730
- package/src/wallet/Cashtokens.test.ts +0 -1411
- package/src/wallet/HDWallet.test.ts +0 -1086
- package/src/wallet/HDWallet.ts +0 -992
- package/src/wallet/Util.test.ts +0 -134
- package/src/wallet/Util.ts +0 -191
- package/src/wallet/WalletCache.test.ts +0 -45
- package/src/wallet/Watch.ts +0 -441
- package/src/wallet/Wif.bip39.test.ts +0 -48
- package/src/wallet/Wif.test.ts +0 -1189
- package/src/wallet/Wif.ts +0 -687
- package/src/wallet/Wif.watchOnly.test.ts +0 -58
- package/src/wallet/createWallet.ts +0 -238
- package/src/wallet/enum.ts +0 -18
- package/src/wallet/interface.ts +0 -102
- package/src/wallet/model.test.ts +0 -24
- package/src/wallet/model.ts +0 -352
- package/tsconfig.browser.json +0 -11
- package/tsconfig.json +0 -33
- package/webpack.config.cjs +0 -132
|
@@ -1,1086 +0,0 @@
|
|
|
1
|
-
import { assertSuccess, decodeTransaction, hexToBin } from "@bitauth/libauth";
|
|
2
|
-
import { HDWallet, RegTestHDWallet, GAP_SIZE } from "./HDWallet";
|
|
3
|
-
import { RegTestWallet, Wallet } from "./Wif";
|
|
4
|
-
import { Config } from "../config";
|
|
5
|
-
import { getNextUnusedIndex } from "../util/hd";
|
|
6
|
-
import { NFTCapability } from "../interface";
|
|
7
|
-
import { TokenMintRequest, TokenSendRequest } from "./model";
|
|
8
|
-
import { stringify } from "../cache";
|
|
9
|
-
import { mine } from "../mine";
|
|
10
|
-
import { delay } from "../util/delay";
|
|
11
|
-
import { CancelFn } from "./interface";
|
|
12
|
-
|
|
13
|
-
const expectedXpub =
|
|
14
|
-
"xpub6CGqRCnS5qDfyxtzV3y3tj8CY7qf3z3GiB2qnCUTdNkhpNxbLtobrU5ZXBVPG3rzPcBUpJAoj3K1u1jyDwKuduL71gLPm27Tckc85apgQRr";
|
|
15
|
-
const expectedXprv =
|
|
16
|
-
"xprv9yHV1hFYFTfNmUpXP2S3XbBTz61AeXKRLx7Eyp4r53DiwadSoMVMJfm5fvtxBc3NFKfozcH42LM66Kb5VaxdLvGk43JWahCegx6iaEJbkB2";
|
|
17
|
-
|
|
18
|
-
describe("HDWallet", () => {
|
|
19
|
-
it("should create a new HDWallet instance", async () => {
|
|
20
|
-
const wallet = await Wallet.fromSeed(
|
|
21
|
-
"divide battle bulb improve hockey favorite charge save merit fatal frog cage"
|
|
22
|
-
);
|
|
23
|
-
const walletSeed = await HDWallet.fromSeed(
|
|
24
|
-
"divide battle bulb improve hockey favorite charge save merit fatal frog cage"
|
|
25
|
-
);
|
|
26
|
-
const walletPriv = await HDWallet.fromXPriv(expectedXprv);
|
|
27
|
-
const walletPub = await HDWallet.fromXPub(expectedXpub);
|
|
28
|
-
|
|
29
|
-
expect(walletSeed.xPub).toBe(expectedXpub);
|
|
30
|
-
expect(walletSeed.xPriv).toBe(expectedXprv);
|
|
31
|
-
expect(walletPriv.xPub).toBe(expectedXpub);
|
|
32
|
-
expect(walletPriv.xPriv).toBe(expectedXprv);
|
|
33
|
-
expect(walletPub.xPub).toBe(expectedXpub);
|
|
34
|
-
|
|
35
|
-
expect(wallet.getDepositAddress()).toBe(walletSeed.getDepositAddress());
|
|
36
|
-
expect(wallet.getDepositAddress()).toBe(walletPriv.getDepositAddress());
|
|
37
|
-
expect(wallet.getDepositAddress()).toBe(walletPub.getDepositAddress());
|
|
38
|
-
|
|
39
|
-
expect(walletSeed.getChangeAddress()).toBe(walletPriv.getChangeAddress());
|
|
40
|
-
expect(walletSeed.getChangeAddress()).toBe(walletPub.getChangeAddress());
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("should serialize", async () => {
|
|
44
|
-
const wallet = await HDWallet.fromSeed(
|
|
45
|
-
"divide battle bulb improve hockey favorite charge save merit fatal frog cage"
|
|
46
|
-
);
|
|
47
|
-
expect(wallet.toString()).toBe(
|
|
48
|
-
"hd:mainnet:divide battle bulb improve hockey favorite charge save merit fatal frog cage:m/44'/0'/0':0:0"
|
|
49
|
-
);
|
|
50
|
-
expect(wallet.toDbString()).toBe(
|
|
51
|
-
"hd:mainnet:divide battle bulb improve hockey favorite charge save merit fatal frog cage:m/44'/0'/0':0:0"
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
wallet.name = "testWallet";
|
|
55
|
-
expect(wallet.toString()).toBe("named:mainnet:testWallet");
|
|
56
|
-
expect(wallet.toDbString()).toBe(
|
|
57
|
-
"hd:mainnet:divide battle bulb improve hockey favorite charge save merit fatal frog cage:m/44'/0'/0':0:0"
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const xPrivWallet = await HDWallet.fromXPriv(expectedXprv);
|
|
61
|
-
expect(xPrivWallet.toString()).toBe(
|
|
62
|
-
"hd:mainnet:xprv9yHV1hFYFTfNmUpXP2S3XbBTz61AeXKRLx7Eyp4r53DiwadSoMVMJfm5fvtxBc3NFKfozcH42LM66Kb5VaxdLvGk43JWahCegx6iaEJbkB2:0:0"
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
const xPubWallet = await HDWallet.fromXPub(expectedXpub);
|
|
66
|
-
expect(xPubWallet.toString()).toBe(
|
|
67
|
-
"hd:mainnet:xpub6CGqRCnS5qDfyxtzV3y3tj8CY7qf3z3GiB2qnCUTdNkhpNxbLtobrU5ZXBVPG3rzPcBUpJAoj3K1u1jyDwKuduL71gLPm27Tckc85apgQRr:0:0"
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
const uninitializedWallet = new HDWallet();
|
|
71
|
-
expect(() => uninitializedWallet.toDbString()).toThrowError(
|
|
72
|
-
"HDWallet has no mnemonic, xPriv or xPub to serialize"
|
|
73
|
-
);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("Get next index", () => {
|
|
77
|
-
expect(getNextUnusedIndex(-1, [null, null, null])).toBe(0);
|
|
78
|
-
expect(getNextUnusedIndex(-1, ["", null, null])).toBe(1);
|
|
79
|
-
expect(getNextUnusedIndex(-1, ["", null, ""])).toBe(1);
|
|
80
|
-
expect(getNextUnusedIndex(-1, ["", "", null])).toBe(2);
|
|
81
|
-
expect(getNextUnusedIndex(-1, ["", "", ""])).toBe(3);
|
|
82
|
-
|
|
83
|
-
expect(getNextUnusedIndex(0, [null, null, null])).toBe(0);
|
|
84
|
-
expect(getNextUnusedIndex(1, [null, null, null])).toBe(1);
|
|
85
|
-
expect(getNextUnusedIndex(2, [null, null, null])).toBe(2);
|
|
86
|
-
|
|
87
|
-
expect(
|
|
88
|
-
getNextUnusedIndex(-1, [
|
|
89
|
-
"759933dd4c6d75f097ec75158ebc04a1f89bc484fc6df0352816328fb4f533a4",
|
|
90
|
-
null,
|
|
91
|
-
null,
|
|
92
|
-
null,
|
|
93
|
-
])
|
|
94
|
-
).toBe(1);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("promises", async () => {
|
|
98
|
-
const result = await Promise.all([
|
|
99
|
-
(async () => 1)(),
|
|
100
|
-
new Promise((resolve) => resolve(2)),
|
|
101
|
-
]);
|
|
102
|
-
expect(stringify(result)).toBe(stringify([1, 2]));
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it("deposit indexes", async () => {
|
|
106
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
107
|
-
expect(hdWallet.depositIndex).toBe(0);
|
|
108
|
-
|
|
109
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
110
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
await fundingWallet.send({
|
|
114
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
115
|
-
value: 100000n,
|
|
116
|
-
});
|
|
117
|
-
await hdWallet.waitForUpdate({ depositIndex: 1 });
|
|
118
|
-
expect(hdWallet.depositIndex).toBe(1);
|
|
119
|
-
|
|
120
|
-
await fundingWallet.send({
|
|
121
|
-
cashaddr: hdWallet.getDepositAddress(1),
|
|
122
|
-
value: 100000n,
|
|
123
|
-
});
|
|
124
|
-
await hdWallet.waitForUpdate({ depositIndex: 2 });
|
|
125
|
-
expect(hdWallet.depositIndex).toBe(2);
|
|
126
|
-
|
|
127
|
-
await fundingWallet.send({
|
|
128
|
-
cashaddr: hdWallet.getDepositAddress(4),
|
|
129
|
-
value: 100000n,
|
|
130
|
-
});
|
|
131
|
-
await hdWallet.waitForUpdate({ depositIndex: 5 });
|
|
132
|
-
expect(hdWallet.depositIndex).toBe(5);
|
|
133
|
-
|
|
134
|
-
// beyond gap size, should not update index
|
|
135
|
-
await fundingWallet.send({
|
|
136
|
-
cashaddr: hdWallet.getDepositAddress(30),
|
|
137
|
-
value: 100000n,
|
|
138
|
-
});
|
|
139
|
-
expect(hdWallet.depositIndex).toBe(5);
|
|
140
|
-
|
|
141
|
-
await hdWallet.scanMoreAddresses(30);
|
|
142
|
-
expect(hdWallet.depositIndex).toBe(31);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it("should scan beyond gap to find real deposit index", async () => {
|
|
146
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
147
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
// Create a wallet and fund addresses 0 and 20
|
|
151
|
-
// Initial scan covers 0-19, finds addr 0 used (depositIndex=1)
|
|
152
|
-
// Gap from index 1 to end of scan (19) is 19 < 20, so scanner extends
|
|
153
|
-
// Next batch includes addr 20, finds it used (depositIndex=21)
|
|
154
|
-
const seedWallet = await RegTestHDWallet.newRandom();
|
|
155
|
-
const addr0 = seedWallet.getDepositAddress(0);
|
|
156
|
-
const addr20 = seedWallet.getDepositAddress(20);
|
|
157
|
-
|
|
158
|
-
await fundingWallet.send([
|
|
159
|
-
{ cashaddr: addr0, value: 10000n },
|
|
160
|
-
{ cashaddr: addr20, value: 10000n },
|
|
161
|
-
]);
|
|
162
|
-
// Wait for seedWallet to see both transactions via electrum
|
|
163
|
-
await seedWallet.waitForUpdate({ depositIndex: 21 });
|
|
164
|
-
|
|
165
|
-
// Restore wallet from same seed, starting from index 0
|
|
166
|
-
const restoredWallet = await RegTestHDWallet.fromSeed(
|
|
167
|
-
seedWallet.mnemonic!,
|
|
168
|
-
seedWallet.derivation
|
|
169
|
-
);
|
|
170
|
-
await restoredWallet.watchPromise;
|
|
171
|
-
|
|
172
|
-
expect(restoredWallet.depositIndex).toBe(21);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it("changeIndex updates when spending", async () => {
|
|
176
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
177
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
178
|
-
);
|
|
179
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
180
|
-
const bob = await RegTestWallet.newRandom();
|
|
181
|
-
|
|
182
|
-
expect(hdWallet.depositIndex).toBe(0);
|
|
183
|
-
expect(hdWallet.changeIndex).toBe(0);
|
|
184
|
-
|
|
185
|
-
// fund deposit address 0
|
|
186
|
-
await fundingWallet.send({
|
|
187
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
188
|
-
value: 100000n,
|
|
189
|
-
});
|
|
190
|
-
await hdWallet.waitForUpdate({ depositIndex: 1 });
|
|
191
|
-
expect(hdWallet.depositIndex).toBe(1);
|
|
192
|
-
expect(hdWallet.changeIndex).toBe(0);
|
|
193
|
-
|
|
194
|
-
// spend, which creates change on change address 0
|
|
195
|
-
await hdWallet.send({
|
|
196
|
-
cashaddr: bob.getDepositAddress(),
|
|
197
|
-
value: 50000n,
|
|
198
|
-
});
|
|
199
|
-
await hdWallet.waitForUpdate({ changeIndex: 1 });
|
|
200
|
-
expect(hdWallet.changeIndex).toBe(1);
|
|
201
|
-
|
|
202
|
-
// fund and spend again, change goes to change address 1
|
|
203
|
-
await fundingWallet.send({
|
|
204
|
-
cashaddr: hdWallet.getDepositAddress(),
|
|
205
|
-
value: 100000n,
|
|
206
|
-
});
|
|
207
|
-
await hdWallet.waitForUpdate({ depositIndex: 2 });
|
|
208
|
-
await hdWallet.send({
|
|
209
|
-
cashaddr: bob.getDepositAddress(),
|
|
210
|
-
value: 50000n,
|
|
211
|
-
});
|
|
212
|
-
await hdWallet.waitForUpdate({ changeIndex: 2 });
|
|
213
|
-
expect(hdWallet.changeIndex).toBe(2);
|
|
214
|
-
|
|
215
|
-
// Restore wallet from same seed and verify depositIndex is correct
|
|
216
|
-
const restoredWallet = await RegTestHDWallet.fromSeed(
|
|
217
|
-
hdWallet.mnemonic!,
|
|
218
|
-
hdWallet.derivation
|
|
219
|
-
);
|
|
220
|
-
await restoredWallet.watchPromise;
|
|
221
|
-
|
|
222
|
-
expect(restoredWallet.depositIndex).toBe(hdWallet.depositIndex);
|
|
223
|
-
expect(restoredWallet.changeIndex).toBe(hdWallet.changeIndex);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it("hasAddress should recognize wallet addresses", async () => {
|
|
227
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
228
|
-
|
|
229
|
-
const deposit0 = hdWallet.getDepositAddress(0);
|
|
230
|
-
const deposit1 = hdWallet.getDepositAddress(1);
|
|
231
|
-
const change0 = hdWallet.getChangeAddress(0);
|
|
232
|
-
|
|
233
|
-
expect(hdWallet.hasAddress(deposit0)).toBe(true);
|
|
234
|
-
expect(hdWallet.hasAddress(deposit1)).toBe(true);
|
|
235
|
-
expect(hdWallet.hasAddress(change0)).toBe(true);
|
|
236
|
-
expect(
|
|
237
|
-
hdWallet.hasAddress("bchreg:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9d5dxv4")
|
|
238
|
-
).toBe(false);
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
it("Should send funds from an HDWallet", async () => {
|
|
242
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
243
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
247
|
-
expect(await hdWallet.getBalance()).toBe(0n);
|
|
248
|
-
|
|
249
|
-
const depositAddress = hdWallet.getDepositAddress();
|
|
250
|
-
await fundingWallet.send({
|
|
251
|
-
cashaddr: depositAddress,
|
|
252
|
-
value: 100000n,
|
|
253
|
-
});
|
|
254
|
-
await hdWallet.waitForUpdate({ depositIndex: 1 });
|
|
255
|
-
|
|
256
|
-
expect(await hdWallet.getBalance()).toBe(100000n);
|
|
257
|
-
|
|
258
|
-
const depositAddress2 = hdWallet.getDepositAddress();
|
|
259
|
-
expect(depositAddress).not.toBe(depositAddress2);
|
|
260
|
-
|
|
261
|
-
// send more funds to new deposit address
|
|
262
|
-
await fundingWallet.send({
|
|
263
|
-
cashaddr: depositAddress2,
|
|
264
|
-
value: 100000n,
|
|
265
|
-
});
|
|
266
|
-
await hdWallet.waitForUpdate({ depositIndex: 2 });
|
|
267
|
-
|
|
268
|
-
expect(await hdWallet.getBalance()).toBe(200000n);
|
|
269
|
-
|
|
270
|
-
expect(
|
|
271
|
-
await (
|
|
272
|
-
await RegTestWallet.watchOnly(hdWallet.getDepositAddress(0))
|
|
273
|
-
).getBalance()
|
|
274
|
-
).toBe(100000n);
|
|
275
|
-
expect(
|
|
276
|
-
await (
|
|
277
|
-
await RegTestWallet.watchOnly(hdWallet.getDepositAddress(1))
|
|
278
|
-
).getBalance()
|
|
279
|
-
).toBe(100000n);
|
|
280
|
-
expect(
|
|
281
|
-
await (
|
|
282
|
-
await RegTestWallet.watchOnly(hdWallet.getDepositAddress(2))
|
|
283
|
-
).getBalance()
|
|
284
|
-
).toBe(0n);
|
|
285
|
-
|
|
286
|
-
expect(
|
|
287
|
-
await (
|
|
288
|
-
await RegTestWallet.watchOnly(hdWallet.getChangeAddress(0))
|
|
289
|
-
).getBalance()
|
|
290
|
-
).toBe(0n);
|
|
291
|
-
|
|
292
|
-
const bob = await RegTestWallet.newRandom();
|
|
293
|
-
|
|
294
|
-
await hdWallet.send({
|
|
295
|
-
cashaddr: bob.getDepositAddress(),
|
|
296
|
-
value: 150000n,
|
|
297
|
-
});
|
|
298
|
-
await hdWallet.waitForUpdate({ changeIndex: 1 });
|
|
299
|
-
|
|
300
|
-
expect(
|
|
301
|
-
await (
|
|
302
|
-
await RegTestWallet.watchOnly(hdWallet.getDepositAddress(0))
|
|
303
|
-
).getBalance()
|
|
304
|
-
).toBe(0n);
|
|
305
|
-
expect(
|
|
306
|
-
await (
|
|
307
|
-
await RegTestWallet.watchOnly(hdWallet.getDepositAddress(1))
|
|
308
|
-
).getBalance()
|
|
309
|
-
).toBe(0n);
|
|
310
|
-
expect(
|
|
311
|
-
await (
|
|
312
|
-
await RegTestWallet.watchOnly(hdWallet.getDepositAddress(2))
|
|
313
|
-
).getBalance()
|
|
314
|
-
).toBe(0n);
|
|
315
|
-
|
|
316
|
-
expect(
|
|
317
|
-
await (
|
|
318
|
-
await RegTestWallet.watchOnly(hdWallet.getChangeAddress(0))
|
|
319
|
-
).getBalance()
|
|
320
|
-
).toBeGreaterThan(50000n - 1000n);
|
|
321
|
-
|
|
322
|
-
expect(hdWallet.getChangeAddress()).not.toBe(hdWallet.getChangeAddress(0));
|
|
323
|
-
expect(hdWallet.getChangeAddress()).toBe(hdWallet.getChangeAddress(1));
|
|
324
|
-
|
|
325
|
-
expect(hdWallet.depositIndex).toBe(2);
|
|
326
|
-
expect(hdWallet.changeIndex).toBe(1);
|
|
327
|
-
|
|
328
|
-
expect(await bob.getBalance()).toBe(150000n);
|
|
329
|
-
|
|
330
|
-
expect(await hdWallet.getBalance()).toBe(49639n); // minus fees
|
|
331
|
-
|
|
332
|
-
expect(await hdWallet.getMaxAmountToSend()).toBe(49407n);
|
|
333
|
-
const charlie = await RegTestWallet.newRandom();
|
|
334
|
-
await hdWallet.sendMax(charlie.cashaddr);
|
|
335
|
-
|
|
336
|
-
// Wait for HD wallet to process the spent notification
|
|
337
|
-
while ((await hdWallet.getBalance()) > 0n)
|
|
338
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
339
|
-
|
|
340
|
-
expect(await charlie.getBalance()).toBe(49407n);
|
|
341
|
-
expect(await hdWallet.getBalance()).toBe(0n);
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
it("Should build unsigned transactions from an HDWallet", async () => {
|
|
345
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
346
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
347
|
-
);
|
|
348
|
-
|
|
349
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
350
|
-
expect(await hdWallet.getBalance()).toBe(0n);
|
|
351
|
-
|
|
352
|
-
const depositAddress = hdWallet.getDepositAddress();
|
|
353
|
-
await fundingWallet.send({
|
|
354
|
-
cashaddr: depositAddress,
|
|
355
|
-
value: 100000n,
|
|
356
|
-
});
|
|
357
|
-
await hdWallet.waitForUpdate({ depositIndex: 1 });
|
|
358
|
-
|
|
359
|
-
expect(await hdWallet.getBalance()).toBe(100000n);
|
|
360
|
-
|
|
361
|
-
const unsignedTx = await hdWallet.send(
|
|
362
|
-
{
|
|
363
|
-
cashaddr: (await RegTestWallet.newRandom()).getDepositAddress(),
|
|
364
|
-
value: 50000n,
|
|
365
|
-
},
|
|
366
|
-
{
|
|
367
|
-
buildUnsigned: true,
|
|
368
|
-
}
|
|
369
|
-
);
|
|
370
|
-
|
|
371
|
-
const tx = assertSuccess(
|
|
372
|
-
decodeTransaction(hexToBin(unsignedTx.unsignedTransaction!))
|
|
373
|
-
);
|
|
374
|
-
expect(tx.inputs.length).toBe(1);
|
|
375
|
-
expect(tx.inputs[0].unlockingBytecode.length).toBe(0); // should be empty
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
it("WalletCache persistence, addresses", async () => {
|
|
379
|
-
const memoryCacheValue = Config.UseMemoryCache;
|
|
380
|
-
Config.UseMemoryCache = true;
|
|
381
|
-
|
|
382
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
383
|
-
|
|
384
|
-
// get some addresses to populate cache
|
|
385
|
-
hdWallet.getDepositAddress(0);
|
|
386
|
-
hdWallet.getDepositAddress(100);
|
|
387
|
-
|
|
388
|
-
hdWallet.getChangeAddress(0);
|
|
389
|
-
hdWallet.getChangeAddress(100);
|
|
390
|
-
|
|
391
|
-
// persist cache
|
|
392
|
-
await hdWallet.walletCache.persist();
|
|
393
|
-
|
|
394
|
-
// check cache data is there in other instance
|
|
395
|
-
const otherWallet = await RegTestHDWallet.fromId(hdWallet.toDbString());
|
|
396
|
-
expect(
|
|
397
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(0))
|
|
398
|
-
?.privateKey instanceof Uint8Array
|
|
399
|
-
).toBe(true);
|
|
400
|
-
expect(
|
|
401
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(0))
|
|
402
|
-
?.publicKey instanceof Uint8Array
|
|
403
|
-
).toBe(true);
|
|
404
|
-
expect(
|
|
405
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(0))
|
|
406
|
-
?.publicKeyHash instanceof Uint8Array
|
|
407
|
-
).toBe(true);
|
|
408
|
-
|
|
409
|
-
expect(
|
|
410
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(0))
|
|
411
|
-
).toBeDefined();
|
|
412
|
-
expect(
|
|
413
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(99))
|
|
414
|
-
).not.toBeDefined();
|
|
415
|
-
expect(
|
|
416
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(100))
|
|
417
|
-
).toBeDefined();
|
|
418
|
-
|
|
419
|
-
expect(
|
|
420
|
-
otherWallet.walletCache.get(hdWallet.getChangeAddress(0))
|
|
421
|
-
).toBeDefined();
|
|
422
|
-
expect(
|
|
423
|
-
otherWallet.walletCache.get(hdWallet.getChangeAddress(99))
|
|
424
|
-
).not.toBeDefined();
|
|
425
|
-
expect(
|
|
426
|
-
otherWallet.walletCache.get(hdWallet.getChangeAddress(100))
|
|
427
|
-
).toBeDefined();
|
|
428
|
-
|
|
429
|
-
Config.UseMemoryCache = memoryCacheValue;
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
it("WalletCache persistence, status and utxo", async () => {
|
|
433
|
-
const memoryCacheValue = Config.UseMemoryCache;
|
|
434
|
-
Config.UseMemoryCache = true;
|
|
435
|
-
|
|
436
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
437
|
-
|
|
438
|
-
// get some addresses to populate cache
|
|
439
|
-
hdWallet.getDepositAddress(0);
|
|
440
|
-
expect(
|
|
441
|
-
hdWallet.walletCache.get(hdWallet.getDepositAddress(0))?.status
|
|
442
|
-
).toBeNull();
|
|
443
|
-
|
|
444
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
445
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
446
|
-
);
|
|
447
|
-
await fundingWallet.send({
|
|
448
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
449
|
-
value: 100000n,
|
|
450
|
-
});
|
|
451
|
-
await hdWallet.waitForUpdate({ depositIndex: 1 });
|
|
452
|
-
|
|
453
|
-
expect(
|
|
454
|
-
hdWallet.walletCache.get(hdWallet.getDepositAddress(0))?.status
|
|
455
|
-
).not.toBeNull();
|
|
456
|
-
expect(
|
|
457
|
-
hdWallet.walletCache.get(hdWallet.getDepositAddress(0))?.utxos.length
|
|
458
|
-
).toBe(1);
|
|
459
|
-
|
|
460
|
-
// persist cache
|
|
461
|
-
await hdWallet.walletCache.persist();
|
|
462
|
-
|
|
463
|
-
// check cache data is there in other instance
|
|
464
|
-
const otherWallet = await RegTestHDWallet.fromId(hdWallet.toDbString());
|
|
465
|
-
await otherWallet.watchPromise; // ensure any async init is done
|
|
466
|
-
expect(
|
|
467
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(0))?.status
|
|
468
|
-
).not.toBeNull();
|
|
469
|
-
expect(
|
|
470
|
-
hdWallet.walletCache.get(hdWallet.getDepositAddress(0))?.utxos.length
|
|
471
|
-
).toBe(1);
|
|
472
|
-
expect(
|
|
473
|
-
stringify(hdWallet.walletCache.get(hdWallet.getDepositAddress(0))?.utxos)
|
|
474
|
-
).toBe(
|
|
475
|
-
stringify(
|
|
476
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(0))?.utxos
|
|
477
|
-
)
|
|
478
|
-
);
|
|
479
|
-
|
|
480
|
-
Config.UseMemoryCache = memoryCacheValue;
|
|
481
|
-
});
|
|
482
|
-
|
|
483
|
-
it("WalletCache persistence, rawHistory", async () => {
|
|
484
|
-
const memoryCacheValue = Config.UseMemoryCache;
|
|
485
|
-
Config.UseMemoryCache = true;
|
|
486
|
-
|
|
487
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
488
|
-
|
|
489
|
-
// get deposit address to populate cache
|
|
490
|
-
hdWallet.getDepositAddress(0);
|
|
491
|
-
expect(
|
|
492
|
-
hdWallet.walletCache.get(hdWallet.getDepositAddress(0))?.rawHistory
|
|
493
|
-
).toEqual([]);
|
|
494
|
-
|
|
495
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
496
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
497
|
-
);
|
|
498
|
-
await fundingWallet.send({
|
|
499
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
500
|
-
value: 100000n,
|
|
501
|
-
});
|
|
502
|
-
await hdWallet.waitForUpdate({ depositIndex: 1 });
|
|
503
|
-
|
|
504
|
-
// rawHistory should now have one entry
|
|
505
|
-
expect(
|
|
506
|
-
hdWallet.walletCache.get(hdWallet.getDepositAddress(0))?.rawHistory.length
|
|
507
|
-
).toBe(1);
|
|
508
|
-
|
|
509
|
-
// persist cache
|
|
510
|
-
await hdWallet.walletCache.persist();
|
|
511
|
-
|
|
512
|
-
// check cache data is there in other instance
|
|
513
|
-
const otherWallet = await RegTestHDWallet.fromId(hdWallet.toDbString());
|
|
514
|
-
await otherWallet.watchPromise;
|
|
515
|
-
expect(
|
|
516
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(0))?.rawHistory
|
|
517
|
-
.length
|
|
518
|
-
).toBe(1);
|
|
519
|
-
expect(
|
|
520
|
-
stringify(
|
|
521
|
-
hdWallet.walletCache.get(hdWallet.getDepositAddress(0))?.rawHistory
|
|
522
|
-
)
|
|
523
|
-
).toBe(
|
|
524
|
-
stringify(
|
|
525
|
-
otherWallet.walletCache.get(hdWallet.getDepositAddress(0))?.rawHistory
|
|
526
|
-
)
|
|
527
|
-
);
|
|
528
|
-
|
|
529
|
-
Config.UseMemoryCache = memoryCacheValue;
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
it("getRawHistory uses cached data", async () => {
|
|
533
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
534
|
-
|
|
535
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
536
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
537
|
-
);
|
|
538
|
-
|
|
539
|
-
// Send to multiple deposit addresses
|
|
540
|
-
await fundingWallet.send({
|
|
541
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
542
|
-
value: 100000n,
|
|
543
|
-
});
|
|
544
|
-
await hdWallet.waitForUpdate({ depositIndex: 1 });
|
|
545
|
-
|
|
546
|
-
await fundingWallet.send({
|
|
547
|
-
cashaddr: hdWallet.getDepositAddress(1),
|
|
548
|
-
value: 100000n,
|
|
549
|
-
});
|
|
550
|
-
await hdWallet.waitForUpdate({ depositIndex: 2 });
|
|
551
|
-
|
|
552
|
-
// Check depositRawHistory arrays are populated
|
|
553
|
-
expect(hdWallet.depositRawHistory[0].length).toBe(1);
|
|
554
|
-
expect(hdWallet.depositRawHistory[1].length).toBe(1);
|
|
555
|
-
|
|
556
|
-
// getRawHistory should return deduplicated history from cache
|
|
557
|
-
const rawHistory = await hdWallet.getRawHistory();
|
|
558
|
-
expect(rawHistory.length).toBe(2);
|
|
559
|
-
|
|
560
|
-
// Verify history items have expected structure
|
|
561
|
-
expect(rawHistory[0]).toHaveProperty("tx_hash");
|
|
562
|
-
expect(rawHistory[0]).toHaveProperty("height");
|
|
563
|
-
});
|
|
564
|
-
|
|
565
|
-
it("getHistory works with cached rawHistory", async () => {
|
|
566
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
567
|
-
|
|
568
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
569
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
570
|
-
);
|
|
571
|
-
|
|
572
|
-
await fundingWallet.send({
|
|
573
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
574
|
-
value: 100000n,
|
|
575
|
-
});
|
|
576
|
-
await hdWallet.waitForUpdate({ depositIndex: 1 });
|
|
577
|
-
|
|
578
|
-
const history = await hdWallet.getHistory({ unit: "sat" });
|
|
579
|
-
expect(history.length).toBe(1);
|
|
580
|
-
expect(history[0].valueChange).toBe(100000);
|
|
581
|
-
});
|
|
582
|
-
|
|
583
|
-
it("incremental history fetching with lastConfirmedHeight", async () => {
|
|
584
|
-
const memoryCacheValue = Config.UseMemoryCache;
|
|
585
|
-
Config.UseMemoryCache = true;
|
|
586
|
-
|
|
587
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
588
|
-
|
|
589
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
590
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
591
|
-
);
|
|
592
|
-
|
|
593
|
-
// First transaction
|
|
594
|
-
await fundingWallet.send({
|
|
595
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
596
|
-
value: 50000n,
|
|
597
|
-
});
|
|
598
|
-
await hdWallet.waitForUpdate({ depositIndex: 1 });
|
|
599
|
-
|
|
600
|
-
// Check rawHistory is populated
|
|
601
|
-
const cacheEntry1 = hdWallet.walletCache.get(hdWallet.getDepositAddress(0));
|
|
602
|
-
expect(cacheEntry1?.rawHistory.length).toBe(1);
|
|
603
|
-
// lastConfirmedHeight may be 0 if tx is unconfirmed
|
|
604
|
-
expect(cacheEntry1?.lastConfirmedHeight).toBeGreaterThanOrEqual(0);
|
|
605
|
-
|
|
606
|
-
// Second transaction to same address
|
|
607
|
-
await fundingWallet.send({
|
|
608
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
609
|
-
value: 60000n,
|
|
610
|
-
});
|
|
611
|
-
while (hdWallet.depositRawHistory[0].length < 2)
|
|
612
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
613
|
-
|
|
614
|
-
// Check history accumulated correctly
|
|
615
|
-
const cacheEntry2 = hdWallet.walletCache.get(hdWallet.getDepositAddress(0));
|
|
616
|
-
expect(cacheEntry2?.rawHistory.length).toBe(2);
|
|
617
|
-
|
|
618
|
-
// Verify getRawHistory returns both transactions
|
|
619
|
-
const rawHistory = await hdWallet.getRawHistory();
|
|
620
|
-
expect(rawHistory.length).toBe(2);
|
|
621
|
-
|
|
622
|
-
// Persist and reload - cache should be preserved
|
|
623
|
-
await hdWallet.walletCache.persist();
|
|
624
|
-
const otherWallet = await RegTestHDWallet.fromId(hdWallet.toDbString());
|
|
625
|
-
await otherWallet.watchPromise;
|
|
626
|
-
|
|
627
|
-
const reloadedEntry = otherWallet.walletCache.get(
|
|
628
|
-
hdWallet.getDepositAddress(0)
|
|
629
|
-
);
|
|
630
|
-
expect(reloadedEntry?.lastConfirmedHeight).toBe(
|
|
631
|
-
cacheEntry2?.lastConfirmedHeight
|
|
632
|
-
);
|
|
633
|
-
expect(reloadedEntry?.rawHistory.length).toBe(2);
|
|
634
|
-
|
|
635
|
-
Config.UseMemoryCache = memoryCacheValue;
|
|
636
|
-
});
|
|
637
|
-
|
|
638
|
-
it("watchWallet registers and removes callbacks", async () => {
|
|
639
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
640
|
-
|
|
641
|
-
const cancel = await hdWallet.watchStatus(() => {});
|
|
642
|
-
|
|
643
|
-
// Verify callback was registered
|
|
644
|
-
expect((hdWallet as any).walletWatchCallbacks.length).toBe(1);
|
|
645
|
-
|
|
646
|
-
// Cancel
|
|
647
|
-
await cancel();
|
|
648
|
-
|
|
649
|
-
// Verify callback was removed
|
|
650
|
-
expect((hdWallet as any).walletWatchCallbacks.length).toBe(0);
|
|
651
|
-
});
|
|
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
|
-
|
|
680
|
-
it("watchWallet supports multiple watchers", async () => {
|
|
681
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
682
|
-
|
|
683
|
-
const cancel1 = await hdWallet.watchStatus(() => {});
|
|
684
|
-
const cancel2 = await hdWallet.watchStatus(() => {});
|
|
685
|
-
|
|
686
|
-
// Verify both callbacks registered
|
|
687
|
-
expect((hdWallet as any).walletWatchCallbacks.length).toBe(2);
|
|
688
|
-
|
|
689
|
-
// Cancel one watcher
|
|
690
|
-
await cancel1();
|
|
691
|
-
expect((hdWallet as any).walletWatchCallbacks.length).toBe(1);
|
|
692
|
-
|
|
693
|
-
await cancel2();
|
|
694
|
-
expect((hdWallet as any).walletWatchCallbacks.length).toBe(0);
|
|
695
|
-
});
|
|
696
|
-
|
|
697
|
-
it("watchWalletBalance sets up callback correctly", async () => {
|
|
698
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
699
|
-
|
|
700
|
-
const cancel = await hdWallet.watchBalance(() => {});
|
|
701
|
-
|
|
702
|
-
// Verify callback was registered via watchWallet
|
|
703
|
-
expect((hdWallet as any).walletWatchCallbacks.length).toBe(1);
|
|
704
|
-
|
|
705
|
-
await cancel();
|
|
706
|
-
expect((hdWallet as any).walletWatchCallbacks.length).toBe(0);
|
|
707
|
-
});
|
|
708
|
-
|
|
709
|
-
it("watchWalletTransactions sets up callback correctly", async () => {
|
|
710
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
711
|
-
|
|
712
|
-
const cancel = await hdWallet.watchTransactions(() => {});
|
|
713
|
-
|
|
714
|
-
// Verify callback was registered via watchWallet
|
|
715
|
-
expect((hdWallet as any).walletWatchCallbacks.length).toBe(1);
|
|
716
|
-
|
|
717
|
-
await cancel();
|
|
718
|
-
expect((hdWallet as any).walletWatchCallbacks.length).toBe(0);
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
it("Cashtokens integration test", async () => {
|
|
722
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
723
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
724
|
-
);
|
|
725
|
-
const alice = await RegTestHDWallet.newRandom();
|
|
726
|
-
await fundingWallet.send({
|
|
727
|
-
cashaddr: alice.getDepositAddress(),
|
|
728
|
-
value: 1000000n,
|
|
729
|
-
});
|
|
730
|
-
await alice.waitForUpdate({ depositIndex: 1 });
|
|
731
|
-
|
|
732
|
-
const genesisResponse = await alice.tokenGenesis({
|
|
733
|
-
cashaddr: alice.getDepositAddress(1),
|
|
734
|
-
nft: {
|
|
735
|
-
capability: NFTCapability.minting,
|
|
736
|
-
commitment: "abcd",
|
|
737
|
-
},
|
|
738
|
-
amount: 1000n,
|
|
739
|
-
});
|
|
740
|
-
|
|
741
|
-
const tokenId = genesisResponse.categories![0];
|
|
742
|
-
|
|
743
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
744
|
-
|
|
745
|
-
// mint 2 NFTs, amount reducing
|
|
746
|
-
const response = await alice.tokenMint(tokenId, [
|
|
747
|
-
new TokenMintRequest({
|
|
748
|
-
cashaddr: alice.getDepositAddress(2),
|
|
749
|
-
nft: {
|
|
750
|
-
capability: NFTCapability.none,
|
|
751
|
-
commitment: "",
|
|
752
|
-
},
|
|
753
|
-
}),
|
|
754
|
-
new TokenMintRequest({
|
|
755
|
-
cashaddr: alice.getDepositAddress(3),
|
|
756
|
-
nft: {
|
|
757
|
-
capability: NFTCapability.mutable,
|
|
758
|
-
commitment: "00",
|
|
759
|
-
},
|
|
760
|
-
}),
|
|
761
|
-
]);
|
|
762
|
-
|
|
763
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
764
|
-
|
|
765
|
-
const newTokenUtxos = await alice.getTokenUtxos(tokenId);
|
|
766
|
-
expect(newTokenUtxos.length).toBe(3);
|
|
767
|
-
expect(tokenId).toEqual(response.categories![0]);
|
|
768
|
-
|
|
769
|
-
const bob = await RegTestWallet.newRandom();
|
|
770
|
-
await alice.send([
|
|
771
|
-
new TokenSendRequest({
|
|
772
|
-
cashaddr: bob.cashaddr!,
|
|
773
|
-
category: tokenId,
|
|
774
|
-
nft: {
|
|
775
|
-
capability: NFTCapability.minting,
|
|
776
|
-
commitment: "abcd",
|
|
777
|
-
},
|
|
778
|
-
amount: 1000n,
|
|
779
|
-
}),
|
|
780
|
-
new TokenSendRequest({
|
|
781
|
-
cashaddr: bob.cashaddr!,
|
|
782
|
-
category: tokenId,
|
|
783
|
-
nft: {
|
|
784
|
-
capability: NFTCapability.none,
|
|
785
|
-
commitment: "",
|
|
786
|
-
},
|
|
787
|
-
}),
|
|
788
|
-
new TokenSendRequest({
|
|
789
|
-
cashaddr: bob.cashaddr!,
|
|
790
|
-
category: tokenId,
|
|
791
|
-
nft: {
|
|
792
|
-
capability: NFTCapability.mutable,
|
|
793
|
-
commitment: "00",
|
|
794
|
-
},
|
|
795
|
-
}),
|
|
796
|
-
]);
|
|
797
|
-
|
|
798
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
799
|
-
|
|
800
|
-
expect((await alice.getTokenUtxos(tokenId)).length).toBe(0);
|
|
801
|
-
const bobTokenUtxos = await bob.getTokenUtxos(tokenId);
|
|
802
|
-
expect(bobTokenUtxos.length).toBe(3);
|
|
803
|
-
expect(tokenId).toEqual(response.categories![0]);
|
|
804
|
-
});
|
|
805
|
-
|
|
806
|
-
test("Test enforcing token addresses", async () => {
|
|
807
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
808
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
809
|
-
);
|
|
810
|
-
const alice = await RegTestHDWallet.newRandom();
|
|
811
|
-
await fundingWallet.send({
|
|
812
|
-
cashaddr: alice.getDepositAddress(),
|
|
813
|
-
value: 1000000n,
|
|
814
|
-
});
|
|
815
|
-
await alice.waitForUpdate({ depositIndex: 1 });
|
|
816
|
-
|
|
817
|
-
const genesisResponse = await alice.tokenGenesis({
|
|
818
|
-
amount: 100n,
|
|
819
|
-
});
|
|
820
|
-
const category = genesisResponse.categories![0];
|
|
821
|
-
|
|
822
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
823
|
-
|
|
824
|
-
const previousValue = Config.EnforceCashTokenReceiptAddresses;
|
|
825
|
-
|
|
826
|
-
const wrap = (addr) => {
|
|
827
|
-
return new Promise((resolve) => {
|
|
828
|
-
resolve(new TokenSendRequest({ cashaddr: addr, category: "" }));
|
|
829
|
-
});
|
|
830
|
-
};
|
|
831
|
-
|
|
832
|
-
Config.EnforceCashTokenReceiptAddresses = false;
|
|
833
|
-
await expect(wrap(alice.getDepositAddress())).resolves.not.toThrow();
|
|
834
|
-
await expect(wrap(alice.getTokenDepositAddress())).resolves.not.toThrow();
|
|
835
|
-
|
|
836
|
-
await expect(
|
|
837
|
-
alice.send(
|
|
838
|
-
new TokenSendRequest({
|
|
839
|
-
cashaddr: alice.getDepositAddress(),
|
|
840
|
-
category: category,
|
|
841
|
-
amount: 1n,
|
|
842
|
-
})
|
|
843
|
-
)
|
|
844
|
-
).resolves.not.toThrow();
|
|
845
|
-
|
|
846
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
847
|
-
|
|
848
|
-
await expect(
|
|
849
|
-
alice.send(
|
|
850
|
-
new TokenSendRequest({
|
|
851
|
-
cashaddr: alice.getTokenDepositAddress(),
|
|
852
|
-
category: category,
|
|
853
|
-
amount: 2n,
|
|
854
|
-
})
|
|
855
|
-
)
|
|
856
|
-
).resolves.not.toThrow();
|
|
857
|
-
|
|
858
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
859
|
-
|
|
860
|
-
Config.EnforceCashTokenReceiptAddresses = true;
|
|
861
|
-
await expect(wrap(alice.getDepositAddress())).rejects.toThrow();
|
|
862
|
-
await expect(wrap(alice.getTokenDepositAddress())).resolves.not.toThrow();
|
|
863
|
-
|
|
864
|
-
await expect(
|
|
865
|
-
(async () =>
|
|
866
|
-
await alice.send(
|
|
867
|
-
new TokenSendRequest({
|
|
868
|
-
cashaddr: alice.getDepositAddress(),
|
|
869
|
-
category: category,
|
|
870
|
-
amount: 1n,
|
|
871
|
-
})
|
|
872
|
-
))()
|
|
873
|
-
).rejects.toThrow();
|
|
874
|
-
|
|
875
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
876
|
-
|
|
877
|
-
await expect(
|
|
878
|
-
alice.send(
|
|
879
|
-
new TokenSendRequest({
|
|
880
|
-
cashaddr: alice.getTokenDepositAddress(),
|
|
881
|
-
category: category,
|
|
882
|
-
amount: 2n,
|
|
883
|
-
})
|
|
884
|
-
)
|
|
885
|
-
).resolves.not.toThrow();
|
|
886
|
-
|
|
887
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
888
|
-
|
|
889
|
-
Config.EnforceCashTokenReceiptAddresses = previousValue;
|
|
890
|
-
});
|
|
891
|
-
|
|
892
|
-
it("watchTransactionHashes reports new transactions on HD wallet", async () => {
|
|
893
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
894
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
895
|
-
);
|
|
896
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
897
|
-
|
|
898
|
-
// Fund the HD wallet at deposit address 0
|
|
899
|
-
await fundingWallet.send({
|
|
900
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
901
|
-
value: 100000n,
|
|
902
|
-
});
|
|
903
|
-
await mine({ cashaddr: hdWallet.getDepositAddress(0), blocks: 1 });
|
|
904
|
-
await delay(2000);
|
|
905
|
-
|
|
906
|
-
// Set up watchTransactionHashes, collect reported tx hashes
|
|
907
|
-
const reportedHashes: string[] = [];
|
|
908
|
-
let cancelWatch: CancelFn;
|
|
909
|
-
cancelWatch = await hdWallet.watchTransactionHashes((txHash) => {
|
|
910
|
-
reportedHashes.push(txHash);
|
|
911
|
-
});
|
|
912
|
-
|
|
913
|
-
// Wait for initial callback to fire with existing tx
|
|
914
|
-
await delay(2000);
|
|
915
|
-
|
|
916
|
-
// Send a new transaction to the HD wallet
|
|
917
|
-
const sendResponse = await fundingWallet.send({
|
|
918
|
-
cashaddr: hdWallet.getDepositAddress(),
|
|
919
|
-
value: 50000n,
|
|
920
|
-
});
|
|
921
|
-
await mine({ cashaddr: hdWallet.getDepositAddress(0), blocks: 1 });
|
|
922
|
-
await delay(2000);
|
|
923
|
-
|
|
924
|
-
await cancelWatch();
|
|
925
|
-
|
|
926
|
-
// The new transaction's txId should appear in collected hashes
|
|
927
|
-
expect(reportedHashes).toContain(sendResponse.txId);
|
|
928
|
-
});
|
|
929
|
-
|
|
930
|
-
it("watchTransactionHashes does not re-report old transactions", async () => {
|
|
931
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
932
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
933
|
-
);
|
|
934
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
935
|
-
|
|
936
|
-
// Start watching before any transactions so the first funding triggers a callback
|
|
937
|
-
const reportedHashes: string[] = [];
|
|
938
|
-
let cancelWatch: CancelFn;
|
|
939
|
-
cancelWatch = await hdWallet.watchTransactionHashes((txHash) => {
|
|
940
|
-
reportedHashes.push(txHash);
|
|
941
|
-
});
|
|
942
|
-
|
|
943
|
-
// Fund the HD wallet at deposit address 0
|
|
944
|
-
const fundResponse = await fundingWallet.send({
|
|
945
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
946
|
-
value: 100000n,
|
|
947
|
-
});
|
|
948
|
-
await mine({ cashaddr: hdWallet.getDepositAddress(0), blocks: 1 });
|
|
949
|
-
await delay(2000);
|
|
950
|
-
|
|
951
|
-
// Record how many hashes reported so far (the initial set)
|
|
952
|
-
const initialCount = reportedHashes.length;
|
|
953
|
-
expect(reportedHashes).toContain(fundResponse.txId);
|
|
954
|
-
const initialHashes = [...reportedHashes];
|
|
955
|
-
|
|
956
|
-
// Send a second transaction to the HD wallet
|
|
957
|
-
const sendResponse2 = await fundingWallet.send({
|
|
958
|
-
cashaddr: hdWallet.getDepositAddress(),
|
|
959
|
-
value: 50000n,
|
|
960
|
-
});
|
|
961
|
-
await mine({ cashaddr: hdWallet.getDepositAddress(0), blocks: 1 });
|
|
962
|
-
await delay(2000);
|
|
963
|
-
|
|
964
|
-
await cancelWatch();
|
|
965
|
-
|
|
966
|
-
// Hashes reported after the initial set
|
|
967
|
-
const laterHashes = reportedHashes.slice(initialCount);
|
|
968
|
-
|
|
969
|
-
// The second tx hash was reported
|
|
970
|
-
expect(laterHashes).toContain(sendResponse2.txId);
|
|
971
|
-
|
|
972
|
-
// None of the initial tx hashes were reported again after the first callback
|
|
973
|
-
for (const hash of initialHashes) {
|
|
974
|
-
expect(laterHashes).not.toContain(hash);
|
|
975
|
-
}
|
|
976
|
-
});
|
|
977
|
-
|
|
978
|
-
it("watchTransactionHashes handles transactions across multiple deposit addresses", async () => {
|
|
979
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
980
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
981
|
-
);
|
|
982
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
983
|
-
|
|
984
|
-
// Fund deposit address 0
|
|
985
|
-
const fund0Response = await fundingWallet.send({
|
|
986
|
-
cashaddr: hdWallet.getDepositAddress(0),
|
|
987
|
-
value: 100000n,
|
|
988
|
-
});
|
|
989
|
-
await mine({ cashaddr: hdWallet.getDepositAddress(0), blocks: 1 });
|
|
990
|
-
await delay(1000);
|
|
991
|
-
|
|
992
|
-
// Fund deposit address 1
|
|
993
|
-
const fund1Response = await fundingWallet.send({
|
|
994
|
-
cashaddr: hdWallet.getDepositAddress(1),
|
|
995
|
-
value: 100000n,
|
|
996
|
-
});
|
|
997
|
-
await mine({ cashaddr: hdWallet.getDepositAddress(0), blocks: 1 });
|
|
998
|
-
await delay(1000);
|
|
999
|
-
|
|
1000
|
-
// depositIndex should be 2
|
|
1001
|
-
expect(hdWallet.depositIndex).toBe(2);
|
|
1002
|
-
|
|
1003
|
-
// Set up watchTransactionHashes, collect all reported hashes
|
|
1004
|
-
const reportedHashes: string[] = [];
|
|
1005
|
-
let cancelWatch: CancelFn;
|
|
1006
|
-
cancelWatch = await hdWallet.watchTransactionHashes((txHash) => {
|
|
1007
|
-
reportedHashes.push(txHash);
|
|
1008
|
-
});
|
|
1009
|
-
|
|
1010
|
-
// Wait for initial callback to fire
|
|
1011
|
-
await delay(2000);
|
|
1012
|
-
|
|
1013
|
-
// Send a new transaction to the wallet's next deposit address
|
|
1014
|
-
const fund2Response = await fundingWallet.send({
|
|
1015
|
-
cashaddr: hdWallet.getDepositAddress(),
|
|
1016
|
-
value: 50000n,
|
|
1017
|
-
});
|
|
1018
|
-
await mine({ cashaddr: hdWallet.getDepositAddress(0), blocks: 1 });
|
|
1019
|
-
await delay(2000);
|
|
1020
|
-
|
|
1021
|
-
await cancelWatch();
|
|
1022
|
-
|
|
1023
|
-
// All 3 tx hashes appear in the collected output
|
|
1024
|
-
expect(reportedHashes).toContain(fund0Response.txId);
|
|
1025
|
-
expect(reportedHashes).toContain(fund1Response.txId);
|
|
1026
|
-
expect(reportedHashes).toContain(fund2Response.txId);
|
|
1027
|
-
|
|
1028
|
-
// Each tx hash appears exactly once
|
|
1029
|
-
const uniqueHashes = new Set(reportedHashes);
|
|
1030
|
-
expect(uniqueHashes.size).toBe(reportedHashes.length);
|
|
1031
|
-
});
|
|
1032
|
-
|
|
1033
|
-
it("gap is maintained when addresses near the edge are used", async () => {
|
|
1034
|
-
const fundingWallet = await RegTestWallet.fromId(
|
|
1035
|
-
"wif:regtest:cNfsPtqN2bMRS7vH5qd8tR8GMvgXyL5BjnGAKgZ8DYEiCrCCQcP6"
|
|
1036
|
-
);
|
|
1037
|
-
const hdWallet = await RegTestHDWallet.newRandom();
|
|
1038
|
-
await hdWallet.watchPromise;
|
|
1039
|
-
|
|
1040
|
-
// Initially: depositIndex=0, watched addresses 0..(GAP_SIZE-1)
|
|
1041
|
-
expect(hdWallet.depositIndex).toBe(0);
|
|
1042
|
-
const initialWatched = (hdWallet as any).depositStatuses.length;
|
|
1043
|
-
expect(initialWatched).toBe(GAP_SIZE);
|
|
1044
|
-
|
|
1045
|
-
// Fund an address near the edge of the gap
|
|
1046
|
-
const edgeIndex = GAP_SIZE - 2;
|
|
1047
|
-
await fundingWallet.send({
|
|
1048
|
-
cashaddr: hdWallet.getDepositAddress(edgeIndex),
|
|
1049
|
-
value: 10000n,
|
|
1050
|
-
});
|
|
1051
|
-
|
|
1052
|
-
// Wait for the subscription callback to fire and gap extension to complete
|
|
1053
|
-
await hdWallet.waitForUpdate({ depositIndex: edgeIndex + 1 });
|
|
1054
|
-
await delay(1000);
|
|
1055
|
-
|
|
1056
|
-
// depositIndex should have advanced
|
|
1057
|
-
expect(hdWallet.depositIndex).toBe(edgeIndex + 1);
|
|
1058
|
-
|
|
1059
|
-
// The watched range should have extended to maintain the gap
|
|
1060
|
-
const newWatched = (hdWallet as any).depositStatuses.length;
|
|
1061
|
-
expect(newWatched).toBeGreaterThanOrEqual(hdWallet.depositIndex + GAP_SIZE);
|
|
1062
|
-
|
|
1063
|
-
// Verify the new addresses are actually subscribed (watchCancels populated)
|
|
1064
|
-
const watchCancels = (hdWallet as any).depositWatchCancels;
|
|
1065
|
-
for (let i = initialWatched; i < newWatched; i++) {
|
|
1066
|
-
expect(watchCancels[i]).toBeDefined();
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
// Fund an address in the newly extended range to prove it's being watched
|
|
1070
|
-
const newEdge = newWatched - 2;
|
|
1071
|
-
await fundingWallet.send({
|
|
1072
|
-
cashaddr: hdWallet.getDepositAddress(newEdge),
|
|
1073
|
-
value: 10000n,
|
|
1074
|
-
});
|
|
1075
|
-
await hdWallet.waitForUpdate({ depositIndex: newEdge + 1 });
|
|
1076
|
-
await delay(1000);
|
|
1077
|
-
|
|
1078
|
-
expect(hdWallet.depositIndex).toBe(newEdge + 1);
|
|
1079
|
-
|
|
1080
|
-
// Gap should still be maintained after the second extension
|
|
1081
|
-
const finalWatched = (hdWallet as any).depositStatuses.length;
|
|
1082
|
-
expect(finalWatched).toBeGreaterThanOrEqual(
|
|
1083
|
-
hdWallet.depositIndex + GAP_SIZE
|
|
1084
|
-
);
|
|
1085
|
-
});
|
|
1086
|
-
});
|