mainnet-js 2.7.34 → 3.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.html +1 -1
- package/dist/{mainnet-2.7.34.js → mainnet-3.0.0-next.1.js} +728 -708
- package/dist/module/cache/MemoryCache.d.ts +0 -1
- package/dist/module/cache/MemoryCache.d.ts.map +1 -1
- package/dist/module/cache/MemoryCache.js +5 -7
- package/dist/module/cache/MemoryCache.js.map +1 -1
- package/dist/module/cache/index.d.ts +1 -0
- package/dist/module/cache/index.d.ts.map +1 -1
- package/dist/module/cache/index.js +1 -0
- package/dist/module/cache/index.js.map +1 -1
- package/dist/module/cache/walletCache.d.ts +45 -0
- package/dist/module/cache/walletCache.d.ts.map +1 -0
- package/dist/module/cache/walletCache.js +140 -0
- package/dist/module/cache/walletCache.js.map +1 -0
- package/dist/module/chain.d.ts +1 -1
- package/dist/module/chain.js +1 -1
- package/dist/module/chain.js.map +1 -1
- package/dist/module/constant.d.ts +1 -1
- package/dist/module/constant.d.ts.map +1 -1
- package/dist/module/constant.js +1 -1
- package/dist/module/constant.js.map +1 -1
- package/dist/module/enum.d.ts +1 -7
- package/dist/module/enum.d.ts.map +1 -1
- package/dist/module/enum.js +0 -6
- package/dist/module/enum.js.map +1 -1
- package/dist/module/history/{electrumTransformer.d.ts → getHistory.d.ts} +3 -3
- package/dist/module/history/getHistory.d.ts.map +1 -0
- package/dist/module/history/{electrumTransformer.js → getHistory.js} +17 -14
- package/dist/module/history/getHistory.js.map +1 -0
- package/dist/module/index.d.ts +3 -1
- package/dist/module/index.d.ts.map +1 -1
- package/dist/module/index.js +3 -1
- package/dist/module/index.js.map +1 -1
- package/dist/module/interface.d.ts +7 -2
- package/dist/module/interface.d.ts.map +1 -1
- package/dist/module/interface.js.map +1 -1
- package/dist/module/message/interface.d.ts +2 -2
- package/dist/module/message/interface.d.ts.map +1 -1
- package/dist/module/message/interface.js +0 -3
- package/dist/module/message/interface.js.map +1 -1
- package/dist/module/message/signed.d.ts +5 -5
- package/dist/module/message/signed.d.ts.map +1 -1
- package/dist/module/message/signed.js +8 -8
- package/dist/module/message/signed.js.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.d.ts +2 -2
- package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.js +3 -2
- package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
- package/dist/module/network/NetworkProvider.d.ts +2 -2
- package/dist/module/network/NetworkProvider.d.ts.map +1 -1
- package/dist/module/network/constant.js +4 -4
- package/dist/module/network/constant.js.map +1 -1
- package/dist/module/network/getRelayFeeCache.js +2 -2
- package/dist/module/network/getRelayFeeCache.js.map +1 -1
- package/dist/module/rate/ExchangeRate.d.ts +2 -1
- package/dist/module/rate/ExchangeRate.d.ts.map +1 -1
- package/dist/module/rate/ExchangeRate.js +4 -1
- package/dist/module/rate/ExchangeRate.js.map +1 -1
- package/dist/module/transaction/Wif.d.ts +25 -23
- package/dist/module/transaction/Wif.d.ts.map +1 -1
- package/dist/module/transaction/Wif.js +26 -25
- package/dist/module/transaction/Wif.js.map +1 -1
- package/dist/module/transaction/allocateFee.d.ts +3 -3
- package/dist/module/transaction/allocateFee.d.ts.map +1 -1
- package/dist/module/transaction/allocateFee.js +5 -6
- package/dist/module/transaction/allocateFee.js.map +1 -1
- package/dist/module/util/amountInSatoshi.d.ts +1 -1
- package/dist/module/util/amountInSatoshi.d.ts.map +1 -1
- package/dist/module/util/amountInSatoshi.js +3 -9
- package/dist/module/util/amountInSatoshi.js.map +1 -1
- package/dist/module/util/asSendRequestObject.d.ts.map +1 -1
- package/dist/module/util/asSendRequestObject.js +10 -7
- package/dist/module/util/asSendRequestObject.js.map +1 -1
- package/dist/module/util/checkUtxos.d.ts +2 -2
- package/dist/module/util/checkUtxos.d.ts.map +1 -1
- package/dist/module/util/checkUtxos.js +11 -12
- package/dist/module/util/checkUtxos.js.map +1 -1
- package/dist/module/util/convert.d.ts +3 -0
- package/dist/module/util/convert.d.ts.map +1 -1
- package/dist/module/util/convert.js +12 -0
- package/dist/module/util/convert.js.map +1 -1
- package/dist/module/util/deriveCashaddr.d.ts.map +1 -1
- package/dist/module/util/deriveCashaddr.js +6 -0
- 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/hd.d.ts +3 -0
- package/dist/module/util/hd.d.ts.map +1 -0
- package/dist/module/util/hd.js +11 -0
- package/dist/module/util/hd.js.map +1 -0
- package/dist/module/util/index.d.ts +3 -3
- package/dist/module/util/index.d.ts.map +1 -1
- package/dist/module/util/index.js +3 -3
- package/dist/module/util/index.js.map +1 -1
- package/dist/module/util/satoshiToAmount.d.ts +1 -1
- package/dist/module/util/satoshiToAmount.d.ts.map +1 -1
- package/dist/module/util/satoshiToAmount.js +3 -9
- package/dist/module/util/satoshiToAmount.js.map +1 -1
- package/dist/module/util/sumSendRequestAmounts.d.ts.map +1 -1
- package/dist/module/util/sumSendRequestAmounts.js +3 -4
- package/dist/module/util/sumSendRequestAmounts.js.map +1 -1
- package/dist/module/util/sumUtxoValue.d.ts +3 -3
- package/dist/module/util/sumUtxoValue.d.ts.map +1 -1
- package/dist/module/util/sumUtxoValue.js +2 -2
- package/dist/module/util/sumUtxoValue.js.map +1 -1
- package/dist/module/wallet/Base.d.ts +45 -103
- package/dist/module/wallet/Base.d.ts.map +1 -1
- package/dist/module/wallet/Base.js +99 -298
- package/dist/module/wallet/Base.js.map +1 -1
- package/dist/module/wallet/HDWallet.d.ts +164 -0
- package/dist/module/wallet/HDWallet.d.ts.map +1 -0
- package/dist/module/wallet/HDWallet.js +486 -0
- package/dist/module/wallet/HDWallet.js.map +1 -0
- package/dist/module/wallet/Util.js +1 -1
- package/dist/module/wallet/Util.js.map +1 -1
- package/dist/module/wallet/Watch.d.ts +151 -0
- package/dist/module/wallet/Watch.d.ts.map +1 -0
- package/dist/module/wallet/Watch.js +307 -0
- package/dist/module/wallet/Watch.js.map +1 -0
- package/dist/module/wallet/Wif.d.ts +23 -29
- package/dist/module/wallet/Wif.d.ts.map +1 -1
- package/dist/module/wallet/Wif.js +204 -267
- package/dist/module/wallet/Wif.js.map +1 -1
- package/dist/module/wallet/createWallet.d.ts +7 -1
- package/dist/module/wallet/createWallet.d.ts.map +1 -1
- package/dist/module/wallet/createWallet.js +26 -17
- package/dist/module/wallet/createWallet.js.map +1 -1
- package/dist/module/wallet/interface.d.ts +5 -6
- package/dist/module/wallet/interface.d.ts.map +1 -1
- package/dist/module/wallet/model.d.ts +15 -19
- package/dist/module/wallet/model.d.ts.map +1 -1
- package/dist/module/wallet/model.js +5 -25
- package/dist/module/wallet/model.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/cache/MemoryCache.ts +5 -5
- package/src/cache/index.ts +1 -0
- package/src/cache/walletCache.ts +239 -0
- package/src/chain.ts +1 -1
- package/src/constant.ts +1 -1
- package/src/enum.ts +0 -6
- package/src/history/{electrumTransformer.test.ts → getHistory.test.ts} +26 -53
- package/src/history/{electrumTransformer.ts → getHistory.ts} +31 -15
- package/src/index.ts +3 -1
- package/src/interface.ts +8 -2
- package/src/message/interface.ts +2 -28
- package/src/message/signed.test.ts +36 -48
- package/src/message/signed.ts +9 -12
- package/src/network/Connection.test.ts +3 -3
- package/src/network/ElectrumNetworkProvider.ts +5 -5
- package/src/network/NetworkProvider.ts +2 -2
- package/src/network/Rpc.test.ts +3 -4
- package/src/network/constant.ts +4 -4
- package/src/network/getRelayFeeCache.ts +2 -2
- package/src/rate/ExchangeRate.test.ts +2 -44
- package/src/rate/ExchangeRate.ts +5 -2
- package/src/transaction/Wif.ts +59 -52
- package/src/transaction/allocateFee.test.ts +110 -131
- package/src/transaction/allocateFee.ts +14 -15
- package/src/util/amountInSatoshi.test.ts +1 -9
- package/src/util/amountInSatoshi.ts +6 -10
- package/src/util/asSendRequestObject.ts +12 -7
- package/src/util/checkUtxos.ts +21 -26
- package/src/util/convert.ts +18 -0
- package/src/util/deriveCashaddr.ts +8 -0
- package/src/util/deriveNetwork.ts +1 -1
- package/src/util/derivePublicKeyHash.test.ts +0 -13
- package/src/util/hd.ts +16 -0
- package/src/util/index.ts +3 -7
- package/src/util/satoshiToAmount.test.ts +1 -1
- package/src/util/satoshiToAmount.ts +4 -10
- package/src/util/sumSendRequestAmounts.ts +3 -4
- package/src/util/sumUtxoValue.ts +7 -7
- package/src/wallet/Base.ts +147 -420
- package/src/wallet/Cashtokens.test.headless.js +11 -11
- package/src/wallet/Cashtokens.test.ts +36 -37
- package/src/wallet/HDWallet.test.ts +515 -0
- package/src/wallet/HDWallet.ts +764 -0
- package/src/wallet/Util.ts +1 -1
- package/src/wallet/Watch.ts +447 -0
- package/src/wallet/Wif.bip39.test.ts +1 -1
- package/src/wallet/Wif.test.ts +108 -133
- package/src/wallet/Wif.ts +258 -283
- package/src/wallet/createWallet.ts +28 -18
- package/src/wallet/interface.ts +5 -6
- package/src/wallet/model.test.ts +4 -7
- package/src/wallet/model.ts +19 -51
- package/dist/module/history/electrumTransformer.d.ts.map +0 -1
- package/dist/module/history/electrumTransformer.js.map +0 -1
- package/dist/module/util/balanceObjectFromSatoshi.d.ts +0 -8
- package/dist/module/util/balanceObjectFromSatoshi.d.ts.map +0 -1
- package/dist/module/util/balanceObjectFromSatoshi.js +0 -35
- package/dist/module/util/balanceObjectFromSatoshi.js.map +0 -1
- package/src/util/balanceObjectFromSatoshi.test.ts +0 -58
- package/src/util/balanceObjectFromSatoshi.ts +0 -52
package/src/wallet/Base.ts
CHANGED
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
CashAddressNetworkPrefix,
|
|
4
|
-
CashAddressType,
|
|
5
|
-
decodeCashAddress,
|
|
6
|
-
encodeCashAddress,
|
|
7
|
-
} from "@bitauth/libauth";
|
|
8
|
-
import { DUST_UTXO_THRESHOLD } from "../constant.js";
|
|
1
|
+
import { binToHex, CashAddressNetworkPrefix } from "@bitauth/libauth";
|
|
2
|
+
import { WalletCache } from "../cache/walletCache.js";
|
|
9
3
|
import StorageProvider from "../db/StorageProvider.js";
|
|
4
|
+
import { NetworkType, prefixFromNetworkMap } from "../enum.js";
|
|
5
|
+
import { HexHeaderI, NFTCapability, TxI, Utxo, UtxoId } from "../interface.js";
|
|
10
6
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
UnitEnum,
|
|
15
|
-
} from "../enum.js";
|
|
16
|
-
import { getAddressHistory } from "../history/electrumTransformer.js";
|
|
17
|
-
import { TransactionHistoryItem } from "../history/interface.js";
|
|
18
|
-
import { HexHeaderI, NFTCapability, TxI, UtxoI } from "../interface.js";
|
|
19
|
-
import { SignedMessage } from "../message/signed.js";
|
|
7
|
+
SignedMessageResponseI,
|
|
8
|
+
VerifyMessageResponseI,
|
|
9
|
+
} from "../message/interface.js";
|
|
20
10
|
import { getNetworkProvider } from "../network/default.js";
|
|
21
11
|
import ElectrumNetworkProvider from "../network/ElectrumNetworkProvider.js";
|
|
22
12
|
import { getRelayFeeCache } from "../network/getRelayFeeCache.js";
|
|
@@ -26,25 +16,16 @@ import {
|
|
|
26
16
|
getFeeAmount,
|
|
27
17
|
getFeeAmountSimple,
|
|
28
18
|
getSuitableUtxos,
|
|
19
|
+
placeholderPrivateKeyBin,
|
|
29
20
|
} from "../transaction/Wif.js";
|
|
30
|
-
import {
|
|
31
|
-
balanceFromSatoshi,
|
|
32
|
-
BalanceResponse,
|
|
33
|
-
balanceResponseFromSatoshi,
|
|
34
|
-
} from "../util/balanceObjectFromSatoshi.js";
|
|
35
21
|
import { checkUtxos } from "../util/checkUtxos.js";
|
|
36
|
-
import { derivePrefix } from "../util/derivePublicKeyHash.js";
|
|
37
22
|
import {
|
|
38
|
-
amountInSatoshi,
|
|
39
23
|
asSendRequestObject,
|
|
40
|
-
deriveTokenaddr,
|
|
41
24
|
getRuntimePlatform,
|
|
42
|
-
hexToBin,
|
|
43
25
|
sumTokenAmounts,
|
|
44
26
|
sumUtxoValue,
|
|
45
27
|
toTokenaddr,
|
|
46
28
|
} from "../util/index.js";
|
|
47
|
-
import { sanitizeUnit } from "../util/sanitizeUnit.js";
|
|
48
29
|
import { sumSendRequestAmounts } from "../util/sumSendRequestAmounts.js";
|
|
49
30
|
import { FeePaidByEnum, WalletTypeEnum } from "./enum.js";
|
|
50
31
|
import {
|
|
@@ -68,10 +49,12 @@ import {
|
|
|
68
49
|
TokenSendRequest,
|
|
69
50
|
} from "./model.js";
|
|
70
51
|
import { Util } from "./Util.js";
|
|
71
|
-
import {
|
|
52
|
+
import { SignedMessage } from "../message/signed.js";
|
|
72
53
|
|
|
73
|
-
const
|
|
74
|
-
"
|
|
54
|
+
export const placeholderCashAddr =
|
|
55
|
+
"bitcoincash:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqfnhks603";
|
|
56
|
+
export const placeholderTokenAddr =
|
|
57
|
+
"bitcoincash:zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqweyg7usz";
|
|
75
58
|
|
|
76
59
|
/**
|
|
77
60
|
* A class to hold features used by all wallets
|
|
@@ -80,13 +63,14 @@ const placeholderPrivateKey =
|
|
|
80
63
|
export class BaseWallet implements WalletI {
|
|
81
64
|
public static StorageProvider?: typeof StorageProvider;
|
|
82
65
|
|
|
66
|
+
readonly walletCache?: WalletCache;
|
|
83
67
|
readonly provider: ElectrumNetworkProvider;
|
|
84
68
|
readonly network: NetworkType;
|
|
85
69
|
readonly walletType: WalletTypeEnum;
|
|
86
70
|
_slpSemiAware: boolean = false; // a flag which requires an utxo to have more than 546 sats to be spendable and counted in the balance
|
|
87
|
-
readonly publicKeyHash!: Uint8Array;
|
|
88
|
-
readonly cashaddr!: string;
|
|
89
|
-
readonly tokenaddr!: string;
|
|
71
|
+
// readonly publicKeyHash!: Uint8Array;
|
|
72
|
+
// readonly cashaddr!: string;
|
|
73
|
+
// readonly tokenaddr!: string;
|
|
90
74
|
readonly isTestnet: boolean;
|
|
91
75
|
name: string = "";
|
|
92
76
|
_util?: Util;
|
|
@@ -111,16 +95,7 @@ export class BaseWallet implements WalletI {
|
|
|
111
95
|
|
|
112
96
|
// Return wallet info
|
|
113
97
|
public getInfo(): WalletInfoI {
|
|
114
|
-
|
|
115
|
-
cashaddr: this.cashaddr,
|
|
116
|
-
tokenaddr: this.tokenaddr,
|
|
117
|
-
isTestnet: this.isTestnet,
|
|
118
|
-
name: this.name,
|
|
119
|
-
network: this.network as any,
|
|
120
|
-
publicKeyHash: binToHex(this.publicKeyHash),
|
|
121
|
-
walletId: this.toString(),
|
|
122
|
-
walletDbEntry: this.toDbString(),
|
|
123
|
-
};
|
|
98
|
+
throw Error("getInfo not implemented in BaseWallet");
|
|
124
99
|
}
|
|
125
100
|
|
|
126
101
|
public slpSemiAware(value: boolean = true): this {
|
|
@@ -146,7 +121,22 @@ export class BaseWallet implements WalletI {
|
|
|
146
121
|
* @returns The deposit address as a string
|
|
147
122
|
*/
|
|
148
123
|
public getDepositAddress(): string {
|
|
149
|
-
return this.cashaddr;
|
|
124
|
+
// return this.cashaddr;
|
|
125
|
+
throw Error("getDepositAddress not implemented in BaseWallet");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* getChangeAddress - get a wallet change address
|
|
130
|
+
*
|
|
131
|
+
* a high-level function,
|
|
132
|
+
*
|
|
133
|
+
* @see {@link https://rest-unstable.mainnet.cash/api-docs/#/wallet/changeAddress|/wallet/change_address} for REST endpoint
|
|
134
|
+
*
|
|
135
|
+
* @returns The change address as a string
|
|
136
|
+
*/
|
|
137
|
+
public getChangeAddress(): string {
|
|
138
|
+
// return this.cashaddr;
|
|
139
|
+
throw Error("getChangeAddress not implemented in BaseWallet");
|
|
150
140
|
}
|
|
151
141
|
|
|
152
142
|
/**
|
|
@@ -155,7 +145,18 @@ export class BaseWallet implements WalletI {
|
|
|
155
145
|
* @returns The cashtoken aware deposit address as a string
|
|
156
146
|
*/
|
|
157
147
|
public getTokenDepositAddress(): string {
|
|
158
|
-
return this.tokenaddr;
|
|
148
|
+
// return this.tokenaddr;
|
|
149
|
+
throw Error("getTokenDepositAddress not implemented in BaseWallet");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* getTokenDepositAddress - get a cashtoken aware wallet deposit address
|
|
154
|
+
*
|
|
155
|
+
* @returns The cashtoken aware deposit address as a string
|
|
156
|
+
*/
|
|
157
|
+
public getTokenChangeAddress(): string {
|
|
158
|
+
// return this.tokenaddr;
|
|
159
|
+
throw Error("getTokenDepositAddress not implemented in BaseWallet");
|
|
159
160
|
}
|
|
160
161
|
//#endregion Accessors
|
|
161
162
|
|
|
@@ -172,23 +173,6 @@ export class BaseWallet implements WalletI {
|
|
|
172
173
|
this.provider = this.getNetworkProvider(this.network);
|
|
173
174
|
this.isTestnet = this.network === NetworkType.Mainnet ? false : true;
|
|
174
175
|
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* watchOnly - create a watch-only wallet
|
|
178
|
-
*
|
|
179
|
-
* such kind of wallet does not have a private key and is unable to spend any funds
|
|
180
|
-
* however it still allows to use many utility functions such as getting and watching balance, etc.
|
|
181
|
-
*
|
|
182
|
-
* @param address cashaddress, token aware cashaddress of a wallet
|
|
183
|
-
*
|
|
184
|
-
* @returns instantiated wallet
|
|
185
|
-
*/
|
|
186
|
-
public static async watchOnly<T extends typeof BaseWallet>(
|
|
187
|
-
this: T,
|
|
188
|
-
address: string
|
|
189
|
-
) {
|
|
190
|
-
return new this().watchOnly(address) as InstanceType<T>;
|
|
191
|
-
}
|
|
192
176
|
//#endregion Constructors
|
|
193
177
|
|
|
194
178
|
/**
|
|
@@ -230,7 +214,8 @@ export class BaseWallet implements WalletI {
|
|
|
230
214
|
recoveredWallet.name = savedWalletRecord.name;
|
|
231
215
|
return recoveredWallet;
|
|
232
216
|
} else {
|
|
233
|
-
const wallet = await this.
|
|
217
|
+
const wallet = await this.initialize();
|
|
218
|
+
wallet.name = name;
|
|
234
219
|
await db.addWallet(wallet.name, wallet.toDbString());
|
|
235
220
|
await db.close();
|
|
236
221
|
return wallet;
|
|
@@ -314,7 +299,7 @@ export class BaseWallet implements WalletI {
|
|
|
314
299
|
}
|
|
315
300
|
}
|
|
316
301
|
|
|
317
|
-
protected async
|
|
302
|
+
protected async initialize(): Promise<this> {
|
|
318
303
|
return this;
|
|
319
304
|
}
|
|
320
305
|
|
|
@@ -353,55 +338,6 @@ export class BaseWallet implements WalletI {
|
|
|
353
338
|
return explorerUrlMap[this.network] + txId;
|
|
354
339
|
}
|
|
355
340
|
|
|
356
|
-
// returns the public key hash for an address
|
|
357
|
-
public getPublicKeyHash(hex = false): string | Uint8Array {
|
|
358
|
-
if (this.publicKeyHash) {
|
|
359
|
-
return hex ? binToHex(this.publicKeyHash) : this.publicKeyHash;
|
|
360
|
-
} else {
|
|
361
|
-
throw Error(
|
|
362
|
-
"The public key hash for this wallet is not known. If this wallet was created from the constructor directly, calling the deriveInfo() function may help. "
|
|
363
|
-
);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* fromCashaddr - create a watch-only wallet in the network derived from the address
|
|
369
|
-
*
|
|
370
|
-
* such kind of wallet does not have a private key and is unable to spend any funds
|
|
371
|
-
* however it still allows to use many utility functions such as getting and watching balance, etc.
|
|
372
|
-
*
|
|
373
|
-
* @param address cashaddress of a wallet
|
|
374
|
-
*
|
|
375
|
-
* @returns instantiated wallet
|
|
376
|
-
*/
|
|
377
|
-
public static async fromCashaddr<T extends typeof BaseWallet>(
|
|
378
|
-
this: T,
|
|
379
|
-
address: string
|
|
380
|
-
): Promise<InstanceType<T>> {
|
|
381
|
-
const prefix = derivePrefix(address);
|
|
382
|
-
const networkType = networkPrefixMap[prefix] as NetworkType;
|
|
383
|
-
return new this(networkType).watchOnly(address) as InstanceType<T>;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* fromTokenaddr - create a watch-only wallet in the network derived from the address
|
|
388
|
-
*
|
|
389
|
-
* such kind of wallet does not have a private key and is unable to spend any funds
|
|
390
|
-
* however it still allows to use many utility functions such as getting and watching balance, etc.
|
|
391
|
-
*
|
|
392
|
-
* @param address token aware cashaddress of a wallet
|
|
393
|
-
*
|
|
394
|
-
* @returns instantiated wallet
|
|
395
|
-
*/
|
|
396
|
-
public static async fromTokenaddr<T extends typeof BaseWallet>(
|
|
397
|
-
this: T,
|
|
398
|
-
address: string
|
|
399
|
-
): Promise<InstanceType<T>> {
|
|
400
|
-
const prefix = derivePrefix(address);
|
|
401
|
-
const networkType = networkPrefixMap[prefix] as NetworkType;
|
|
402
|
-
return new this(networkType).watchOnly(address) as InstanceType<T>;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
341
|
/**
|
|
406
342
|
* named - create a named wallet
|
|
407
343
|
*
|
|
@@ -411,7 +347,7 @@ export class BaseWallet implements WalletI {
|
|
|
411
347
|
*
|
|
412
348
|
* @returns instantiated wallet
|
|
413
349
|
*/
|
|
414
|
-
public static async named<T extends typeof
|
|
350
|
+
public static async named<T extends typeof BaseWallet>(
|
|
415
351
|
this: T,
|
|
416
352
|
name: string,
|
|
417
353
|
dbName?: string,
|
|
@@ -432,7 +368,7 @@ export class BaseWallet implements WalletI {
|
|
|
432
368
|
*
|
|
433
369
|
* @returns instantiated wallet
|
|
434
370
|
*/
|
|
435
|
-
public static async replaceNamed<T extends typeof
|
|
371
|
+
public static async replaceNamed<T extends typeof BaseWallet>(
|
|
436
372
|
this: T,
|
|
437
373
|
name: string,
|
|
438
374
|
walletId: string,
|
|
@@ -457,119 +393,33 @@ export class BaseWallet implements WalletI {
|
|
|
457
393
|
}
|
|
458
394
|
|
|
459
395
|
protected fromId(walletId: string): Promise<this> {
|
|
460
|
-
|
|
461
|
-
walletId.split(":");
|
|
462
|
-
|
|
463
|
-
if (walletType !== WalletTypeEnum.Watch) {
|
|
464
|
-
throw Error(
|
|
465
|
-
`fromId called on a ${walletType} wallet, expected a ${WalletTypeEnum.Watch} wallet`
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
if (this.network != networkGiven) {
|
|
470
|
-
throw Error(`Network prefix ${networkGiven} to a ${this.network} wallet`);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
if (arg2) {
|
|
474
|
-
return this.watchOnly(`${arg1}:${arg2}`);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
return this.watchOnly(arg1);
|
|
396
|
+
throw Error("fromId not implemented in BaseWallet");
|
|
478
397
|
}
|
|
479
398
|
|
|
480
|
-
// Initialize a watch only wallet from a cash addr
|
|
481
|
-
protected async watchOnly(address: string): Promise<this> {
|
|
482
|
-
// @ts-ignore
|
|
483
|
-
this.walletType = WalletTypeEnum.Watch;
|
|
484
|
-
const addressComponents = address.split(":");
|
|
485
|
-
let addressPrefix: string;
|
|
486
|
-
let addressBase: string;
|
|
487
|
-
if (addressComponents.length === 1) {
|
|
488
|
-
addressBase = addressComponents.shift() as string;
|
|
489
|
-
addressPrefix = derivePrefix(addressBase);
|
|
490
|
-
} else {
|
|
491
|
-
addressPrefix = addressComponents.shift() as string;
|
|
492
|
-
addressBase = addressComponents.shift() as string;
|
|
493
|
-
if (addressPrefix in networkPrefixMap) {
|
|
494
|
-
if (networkPrefixMap[addressPrefix] !== this.network) {
|
|
495
|
-
throw Error(
|
|
496
|
-
`a ${addressPrefix} address cannot be watched from a ${this.network} Wallet`
|
|
497
|
-
);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
const prefixedAddress = `${addressPrefix}:${addressBase}`;
|
|
503
|
-
|
|
504
|
-
// check if a token aware address was provided
|
|
505
|
-
const addressData = decodeCashAddress(prefixedAddress);
|
|
506
|
-
if (typeof addressData === "string") throw addressData;
|
|
507
|
-
|
|
508
|
-
// @ts-ignore
|
|
509
|
-
this.publicKeyHash = addressData.payload;
|
|
510
|
-
|
|
511
|
-
let nonTokenAwareType = addressData.type;
|
|
512
|
-
if (nonTokenAwareType == CashAddressType.p2pkhWithTokens)
|
|
513
|
-
nonTokenAwareType = CashAddressType.p2pkh;
|
|
514
|
-
if (nonTokenAwareType == CashAddressType.p2shWithTokens)
|
|
515
|
-
nonTokenAwareType = CashAddressType.p2sh;
|
|
516
|
-
if (nonTokenAwareType == CashAddressType.p2pkh)
|
|
517
|
-
// @ts-ignore
|
|
518
|
-
this.publicKeyHash = addressData.payload;
|
|
519
|
-
|
|
520
|
-
// @ts-ignore
|
|
521
|
-
this.cashaddr = encodeCashAddress({
|
|
522
|
-
prefix: addressData.prefix as CashAddressNetworkPrefix,
|
|
523
|
-
type: nonTokenAwareType,
|
|
524
|
-
payload: addressData.payload,
|
|
525
|
-
}).address;
|
|
526
|
-
// @ts-ignore
|
|
527
|
-
this.tokenaddr = deriveTokenaddr(addressData.payload, this.networkPrefix);
|
|
528
|
-
|
|
529
|
-
return this;
|
|
530
|
-
}
|
|
531
399
|
//#region Funds
|
|
532
400
|
/**
|
|
533
401
|
* utxos Get unspent outputs for the wallet
|
|
534
402
|
*
|
|
535
403
|
*/
|
|
536
|
-
public async getUtxos() {
|
|
537
|
-
|
|
538
|
-
throw Error("Attempted to get utxos without an address");
|
|
539
|
-
}
|
|
540
|
-
return await this.getAddressUtxos(this.cashaddr);
|
|
404
|
+
public async getUtxos(): Promise<Utxo[]> {
|
|
405
|
+
throw Error("getUtxos not implemented in BaseWallet");
|
|
541
406
|
}
|
|
542
407
|
|
|
543
|
-
// gets wallet balance in sats
|
|
544
|
-
public async getBalance(
|
|
545
|
-
|
|
546
|
-
priceCache = true
|
|
547
|
-
): Promise<BalanceResponse | number> {
|
|
548
|
-
if (rawUnit) {
|
|
549
|
-
const unit = sanitizeUnit(rawUnit);
|
|
550
|
-
return await balanceFromSatoshi(
|
|
551
|
-
await this.getBalanceFromProvider(),
|
|
552
|
-
unit,
|
|
553
|
-
priceCache
|
|
554
|
-
);
|
|
555
|
-
} else {
|
|
556
|
-
return await balanceResponseFromSatoshi(
|
|
557
|
-
await this.getBalanceFromProvider(),
|
|
558
|
-
priceCache
|
|
559
|
-
);
|
|
560
|
-
}
|
|
408
|
+
// gets wallet balance in sats
|
|
409
|
+
public async getBalance(): Promise<bigint> {
|
|
410
|
+
return this.getBalanceFromProvider();
|
|
561
411
|
}
|
|
562
412
|
|
|
563
413
|
// Gets balance by summing value in all utxos in stats
|
|
564
|
-
public async getBalanceFromUtxos(): Promise<
|
|
565
|
-
const utxos = (await this.
|
|
414
|
+
public async getBalanceFromUtxos(): Promise<bigint> {
|
|
415
|
+
const utxos = (await this.getUtxos()).filter(
|
|
566
416
|
(val) => val.token === undefined
|
|
567
417
|
);
|
|
568
418
|
return sumUtxoValue(utxos);
|
|
569
419
|
}
|
|
570
420
|
|
|
571
421
|
// Gets balance from fulcrum
|
|
572
|
-
public async getBalanceFromProvider(): Promise<
|
|
422
|
+
public async getBalanceFromProvider(): Promise<bigint> {
|
|
573
423
|
// Fulcrum reports balance of all utxos, including tokens, which is undesirable
|
|
574
424
|
// // TODO not sure why getting the balance from a provider doesn't work
|
|
575
425
|
// if (this._slpAware || this._slpSemiAware) {
|
|
@@ -582,19 +432,8 @@ export class BaseWallet implements WalletI {
|
|
|
582
432
|
return this.getBalanceFromUtxos();
|
|
583
433
|
}
|
|
584
434
|
|
|
585
|
-
public async getAddressUtxos(address?: string): Promise<
|
|
586
|
-
|
|
587
|
-
address = this.cashaddr;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
if (this._slpSemiAware) {
|
|
591
|
-
const bchUtxos: UtxoI[] = await this.provider.getUtxos(address);
|
|
592
|
-
return bchUtxos.filter(
|
|
593
|
-
(bchutxo) => bchutxo.satoshis > DUST_UTXO_THRESHOLD
|
|
594
|
-
);
|
|
595
|
-
} else {
|
|
596
|
-
return await this.provider.getUtxos(address);
|
|
597
|
-
}
|
|
435
|
+
public async getAddressUtxos(address?: string): Promise<Utxo[]> {
|
|
436
|
+
throw Error("getAddressUtxos not implemented in BaseWallet");
|
|
598
437
|
}
|
|
599
438
|
|
|
600
439
|
// watching for any transaction hash of this wallet
|
|
@@ -627,68 +466,28 @@ export class BaseWallet implements WalletI {
|
|
|
627
466
|
// sets up a callback to be called upon wallet's balance change
|
|
628
467
|
// can be cancelled by calling the function returned from this one
|
|
629
468
|
public async watchBalance(
|
|
630
|
-
callback: (balance:
|
|
469
|
+
callback: (balance: bigint) => void
|
|
631
470
|
): Promise<CancelFn> {
|
|
632
471
|
return this.provider.watchAddressStatus(
|
|
633
472
|
this.getDepositAddress(),
|
|
634
473
|
async (_status: string) => {
|
|
635
|
-
const balance =
|
|
474
|
+
const balance = await this.getBalanceFromProvider();
|
|
636
475
|
callback(balance);
|
|
637
476
|
}
|
|
638
477
|
);
|
|
639
478
|
}
|
|
640
479
|
|
|
641
|
-
// sets up a callback to be called upon wallet's BCH or USD balance change
|
|
642
|
-
// if BCH balance does not change, the callback will be triggered every
|
|
643
|
-
// @param `usdPriceRefreshInterval` milliseconds by polling for new BCH USD price
|
|
644
|
-
// Since we want to be most sensitive to usd value change, we do not use the cached exchange rates
|
|
645
|
-
// can be cancelled by calling the function returned from this one
|
|
646
|
-
public async watchBalanceUsd(
|
|
647
|
-
callback: (balance: BalanceResponse) => void,
|
|
648
|
-
usdPriceRefreshInterval = 30000
|
|
649
|
-
): Promise<CancelFn> {
|
|
650
|
-
let usdPrice = -1;
|
|
651
|
-
|
|
652
|
-
const _callback = async () => {
|
|
653
|
-
const balance = (await this.getBalance(
|
|
654
|
-
undefined,
|
|
655
|
-
false
|
|
656
|
-
)) as BalanceResponse;
|
|
657
|
-
if (usdPrice !== balance.usd!) {
|
|
658
|
-
usdPrice = balance.usd;
|
|
659
|
-
callback(balance);
|
|
660
|
-
}
|
|
661
|
-
};
|
|
662
|
-
|
|
663
|
-
const watchCancel = await this.provider.watchAddressStatus(
|
|
664
|
-
this.getDepositAddress(),
|
|
665
|
-
_callback
|
|
666
|
-
);
|
|
667
|
-
const interval = setInterval(_callback, usdPriceRefreshInterval);
|
|
668
|
-
|
|
669
|
-
return async () => {
|
|
670
|
-
await watchCancel?.();
|
|
671
|
-
clearInterval(interval);
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
|
-
|
|
675
480
|
// waits for address balance to be greater than or equal to the target value
|
|
676
481
|
// this call halts the execution
|
|
677
|
-
public async waitForBalance(
|
|
678
|
-
value: number,
|
|
679
|
-
rawUnit: UnitEnum = UnitEnum.BCH
|
|
680
|
-
): Promise<BalanceResponse> {
|
|
482
|
+
public async waitForBalance(value: bigint): Promise<bigint> {
|
|
681
483
|
return new Promise(async (resolve) => {
|
|
682
484
|
let watchCancel: CancelFn;
|
|
683
|
-
watchCancel = await this.watchBalance(
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
await watchCancel?.();
|
|
688
|
-
resolve(balance);
|
|
689
|
-
}
|
|
485
|
+
watchCancel = await this.watchBalance(async (balance: bigint) => {
|
|
486
|
+
if (balance >= value) {
|
|
487
|
+
await watchCancel?.();
|
|
488
|
+
resolve(balance);
|
|
690
489
|
}
|
|
691
|
-
);
|
|
490
|
+
});
|
|
692
491
|
});
|
|
693
492
|
}
|
|
694
493
|
|
|
@@ -740,14 +539,7 @@ export class BaseWallet implements WalletI {
|
|
|
740
539
|
outputCount: 1,
|
|
741
540
|
options: {},
|
|
742
541
|
}
|
|
743
|
-
): Promise<{ value:
|
|
744
|
-
if (!params.privateKey && params.options?.buildUnsigned !== true) {
|
|
745
|
-
throw Error("Couldn't get network or private key for wallet.");
|
|
746
|
-
}
|
|
747
|
-
if (!this.cashaddr) {
|
|
748
|
-
throw Error("attempted to send without a cashaddr");
|
|
749
|
-
}
|
|
750
|
-
|
|
542
|
+
): Promise<{ value: bigint; utxos: Utxo[] }> {
|
|
751
543
|
if (params.options && params.options.slpSemiAware) {
|
|
752
544
|
this._slpSemiAware = true;
|
|
753
545
|
}
|
|
@@ -760,18 +552,16 @@ export class BaseWallet implements WalletI {
|
|
|
760
552
|
}
|
|
761
553
|
|
|
762
554
|
// get inputs
|
|
763
|
-
let utxos:
|
|
555
|
+
let utxos: Utxo[];
|
|
764
556
|
if (params.options && params.options.utxoIds) {
|
|
765
557
|
utxos = await checkUtxos(
|
|
766
|
-
params.options.utxoIds.map((utxoId:
|
|
558
|
+
params.options.utxoIds.map((utxoId: Utxo | string) =>
|
|
767
559
|
typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId
|
|
768
560
|
),
|
|
769
561
|
this as any
|
|
770
562
|
);
|
|
771
563
|
} else {
|
|
772
|
-
utxos = (await this.
|
|
773
|
-
(utxo) => !utxo.token
|
|
774
|
-
);
|
|
564
|
+
utxos = (await this.getUtxos()).filter((utxo) => !utxo.token);
|
|
775
565
|
}
|
|
776
566
|
|
|
777
567
|
// Get current height to assure recently mined coins are not spent.
|
|
@@ -779,9 +569,8 @@ export class BaseWallet implements WalletI {
|
|
|
779
569
|
|
|
780
570
|
// simulate outputs using the sender's address
|
|
781
571
|
const sendRequest = new SendRequest({
|
|
782
|
-
cashaddr:
|
|
783
|
-
value:
|
|
784
|
-
unit: "sat",
|
|
572
|
+
cashaddr: placeholderCashAddr,
|
|
573
|
+
value: 100n,
|
|
785
574
|
});
|
|
786
575
|
const sendRequests = Array(params.outputCount)
|
|
787
576
|
.fill(0)
|
|
@@ -798,16 +587,15 @@ export class BaseWallet implements WalletI {
|
|
|
798
587
|
const fee = await getFeeAmountSimple({
|
|
799
588
|
utxos: fundingUtxos,
|
|
800
589
|
sendRequests: sendRequests,
|
|
801
|
-
|
|
802
|
-
sourceAddress: this.cashaddr,
|
|
590
|
+
sourceAddress: placeholderCashAddr,
|
|
803
591
|
relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
|
|
804
592
|
feePaidBy: feePaidBy,
|
|
805
593
|
});
|
|
806
594
|
const spendableAmount = sumUtxoValue(fundingUtxos);
|
|
807
595
|
|
|
808
596
|
let result = spendableAmount - fee;
|
|
809
|
-
if (result <
|
|
810
|
-
result =
|
|
597
|
+
if (result < 0n) {
|
|
598
|
+
result = 0n;
|
|
811
599
|
}
|
|
812
600
|
|
|
813
601
|
return { value: result, utxos: fundingUtxos };
|
|
@@ -821,10 +609,10 @@ export class BaseWallet implements WalletI {
|
|
|
821
609
|
outputCount: 1,
|
|
822
610
|
options: {},
|
|
823
611
|
}
|
|
824
|
-
): Promise<
|
|
612
|
+
): Promise<bigint> {
|
|
825
613
|
const { value: result } = await this._getMaxAmountToSend(params);
|
|
826
614
|
|
|
827
|
-
return
|
|
615
|
+
return result;
|
|
828
616
|
}
|
|
829
617
|
|
|
830
618
|
/**
|
|
@@ -864,7 +652,7 @@ export class BaseWallet implements WalletI {
|
|
|
864
652
|
options?.queryBalance === undefined ||
|
|
865
653
|
options?.queryBalance === true
|
|
866
654
|
) {
|
|
867
|
-
resp.balance =
|
|
655
|
+
resp.balance = await this.getBalance();
|
|
868
656
|
}
|
|
869
657
|
} else {
|
|
870
658
|
resp.unsignedTransaction = binToHex(encodedTransaction);
|
|
@@ -919,7 +707,6 @@ export class BaseWallet implements WalletI {
|
|
|
919
707
|
const sendRequest = new SendRequest({
|
|
920
708
|
cashaddr: cashaddr,
|
|
921
709
|
value: maxSpendableAmount,
|
|
922
|
-
unit: "sat",
|
|
923
710
|
});
|
|
924
711
|
|
|
925
712
|
const { encodedTransaction, tokenIds, sourceOutputs } =
|
|
@@ -942,7 +729,7 @@ export class BaseWallet implements WalletI {
|
|
|
942
729
|
options?.queryBalance === undefined ||
|
|
943
730
|
options?.queryBalance === true
|
|
944
731
|
) {
|
|
945
|
-
resp.balance =
|
|
732
|
+
resp.balance = await this.getBalance();
|
|
946
733
|
}
|
|
947
734
|
} else {
|
|
948
735
|
resp.unsignedTransaction = binToHex(encodedTransaction);
|
|
@@ -971,44 +758,38 @@ export class BaseWallet implements WalletI {
|
|
|
971
758
|
) {
|
|
972
759
|
let sendRequests = asSendRequestObject(requests);
|
|
973
760
|
|
|
974
|
-
if (!privateKey && options?.buildUnsigned !== true) {
|
|
975
|
-
throw new Error(`Missing private key`);
|
|
976
|
-
}
|
|
977
|
-
|
|
978
761
|
if (options && options.slpSemiAware) {
|
|
979
762
|
this._slpSemiAware = true;
|
|
980
763
|
}
|
|
981
764
|
|
|
982
|
-
let feePaidBy;
|
|
983
|
-
if (options
|
|
765
|
+
let feePaidBy: FeePaidByEnum;
|
|
766
|
+
if (options?.feePaidBy) {
|
|
984
767
|
feePaidBy = options.feePaidBy;
|
|
985
768
|
} else {
|
|
986
769
|
feePaidBy = FeePaidByEnum.change;
|
|
987
770
|
}
|
|
988
771
|
|
|
989
|
-
let changeAddress;
|
|
990
|
-
if (options
|
|
772
|
+
let changeAddress: string;
|
|
773
|
+
if (options?.changeAddress) {
|
|
991
774
|
changeAddress = options.changeAddress;
|
|
992
775
|
} else {
|
|
993
|
-
changeAddress = this.
|
|
776
|
+
changeAddress = this.getChangeAddress();
|
|
994
777
|
}
|
|
995
778
|
|
|
996
779
|
let checkTokenQuantities: boolean = true;
|
|
997
|
-
if (options
|
|
780
|
+
if (options?.checkTokenQuantities === false) {
|
|
998
781
|
checkTokenQuantities = false;
|
|
999
782
|
}
|
|
1000
783
|
|
|
1001
784
|
// get inputs from options or query all inputs
|
|
1002
|
-
let utxos:
|
|
785
|
+
let utxos: Utxo[] = await this.getUtxos();
|
|
1003
786
|
if (options && options.utxoIds) {
|
|
1004
787
|
utxos = await checkUtxos(
|
|
1005
|
-
options.utxoIds.map((utxoId:
|
|
788
|
+
options.utxoIds.map((utxoId: Utxo | string) =>
|
|
1006
789
|
typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId
|
|
1007
790
|
),
|
|
1008
|
-
|
|
791
|
+
utxos
|
|
1009
792
|
);
|
|
1010
|
-
} else {
|
|
1011
|
-
utxos = await this.getAddressUtxos(this.cashaddr);
|
|
1012
793
|
}
|
|
1013
794
|
|
|
1014
795
|
// filter out token utxos if there are no token requests
|
|
@@ -1020,7 +801,7 @@ export class BaseWallet implements WalletI {
|
|
|
1020
801
|
}
|
|
1021
802
|
|
|
1022
803
|
const addTokenChangeOutputs = (
|
|
1023
|
-
inputs:
|
|
804
|
+
inputs: Utxo[],
|
|
1024
805
|
outputs: SendRequestType[]
|
|
1025
806
|
) => {
|
|
1026
807
|
// Allow for implicit token burn if the total amount sent is less than user had
|
|
@@ -1058,7 +839,7 @@ export class BaseWallet implements WalletI {
|
|
|
1058
839
|
if (diff >= 0) {
|
|
1059
840
|
let available = 0n;
|
|
1060
841
|
let change = 0n;
|
|
1061
|
-
const ensureUtxos:
|
|
842
|
+
const ensureUtxos: Utxo[] = [];
|
|
1062
843
|
for (const token of tokenInputs.filter((val) => val.token?.amount)) {
|
|
1063
844
|
ensureUtxos.push(token);
|
|
1064
845
|
available += token.token!.amount;
|
|
@@ -1084,7 +865,7 @@ export class BaseWallet implements WalletI {
|
|
|
1084
865
|
if (change > 0) {
|
|
1085
866
|
outputs.push(
|
|
1086
867
|
new TokenSendRequest({
|
|
1087
|
-
cashaddr: toTokenaddr(
|
|
868
|
+
cashaddr: toTokenaddr(this.getChangeAddress()),
|
|
1088
869
|
amount: change,
|
|
1089
870
|
tokenId: tokenId,
|
|
1090
871
|
commitment: tokenOutputs[0].commitment,
|
|
@@ -1112,15 +893,14 @@ export class BaseWallet implements WalletI {
|
|
|
1112
893
|
const feeEstimate = await getFeeAmountSimple({
|
|
1113
894
|
utxos: utxos,
|
|
1114
895
|
sendRequests: sendRequests,
|
|
1115
|
-
|
|
1116
|
-
sourceAddress: this.cashaddr,
|
|
896
|
+
sourceAddress: this.getDepositAddress(),
|
|
1117
897
|
relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
|
|
1118
898
|
feePaidBy: feePaidBy,
|
|
1119
899
|
});
|
|
1120
900
|
|
|
1121
901
|
const fundingUtxos = await getSuitableUtxos(
|
|
1122
902
|
utxos,
|
|
1123
|
-
|
|
903
|
+
spendAmount + feeEstimate,
|
|
1124
904
|
bestHeight,
|
|
1125
905
|
feePaidBy,
|
|
1126
906
|
sendRequests,
|
|
@@ -1135,22 +915,22 @@ export class BaseWallet implements WalletI {
|
|
|
1135
915
|
const fee = await getFeeAmount({
|
|
1136
916
|
utxos: fundingUtxos,
|
|
1137
917
|
sendRequests: sendRequests,
|
|
1138
|
-
|
|
1139
|
-
sourceAddress: this.cashaddr,
|
|
918
|
+
sourceAddress: this.getDepositAddress(),
|
|
1140
919
|
relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
|
|
1141
920
|
feePaidBy: feePaidBy,
|
|
921
|
+
walletCache: this.walletCache,
|
|
1142
922
|
});
|
|
1143
923
|
const { encodedTransaction, sourceOutputs } = await buildEncodedTransaction(
|
|
1144
924
|
{
|
|
1145
925
|
inputs: fundingUtxos,
|
|
1146
926
|
outputs: sendRequests,
|
|
1147
|
-
signingKey: privateKey ??
|
|
1148
|
-
sourceAddress: this.cashaddr,
|
|
927
|
+
signingKey: privateKey ?? placeholderPrivateKeyBin,
|
|
1149
928
|
fee,
|
|
1150
929
|
discardChange,
|
|
1151
930
|
feePaidBy,
|
|
1152
931
|
changeAddress,
|
|
1153
932
|
buildUnsigned: options?.buildUnsigned === true,
|
|
933
|
+
walletCache: this.walletCache,
|
|
1154
934
|
}
|
|
1155
935
|
);
|
|
1156
936
|
|
|
@@ -1186,45 +966,7 @@ export class BaseWallet implements WalletI {
|
|
|
1186
966
|
fromHeight: number = 0,
|
|
1187
967
|
toHeight: number = -1
|
|
1188
968
|
): Promise<TxI[]> {
|
|
1189
|
-
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
/**
|
|
1193
|
-
* getHistory gets transaction history of this wallet with most data decoded and ready to present to user
|
|
1194
|
-
* @note balance calculations are valid only if querying to the blockchain tip (`toHeight` === -1, `count` === -1)
|
|
1195
|
-
* @note this method is heavy on network calls, if invoked in browser use of cache is advised, @see `Config.UseLocalStorageCache`
|
|
1196
|
-
* @note this method tries to recreate the history tab view of Electron Cash wallet, however, it may not be 100% accurate if the tnransaction value changes are the same in the same block (ordering)
|
|
1197
|
-
*
|
|
1198
|
-
* @param unit optional, BCH or currency unit to present balance and balance changes. If unit is currency like USD or EUR, balances will be subject to possible rounding errors. Default 0
|
|
1199
|
-
* @param fromHeight optional, if set, history will be limited. Default 0
|
|
1200
|
-
* @param toHeight optional, if set, history will be limited. Default -1, meaning that all history items will be returned, including mempool
|
|
1201
|
-
* @param start optional, if set, the result set will be paginated with offset `start`
|
|
1202
|
-
* @param count optional, if set, the result set will be paginated with `count`. Default -1, meaning that all history items will be returned
|
|
1203
|
-
*
|
|
1204
|
-
* @returns an array of transaction history items, with input values and addresses encoded in cashaddress format. @see `TransactionHistoryItem` type
|
|
1205
|
-
*/
|
|
1206
|
-
public async getHistory({
|
|
1207
|
-
unit = "sat",
|
|
1208
|
-
fromHeight = 0,
|
|
1209
|
-
toHeight = -1,
|
|
1210
|
-
start = 0,
|
|
1211
|
-
count = -1,
|
|
1212
|
-
}: {
|
|
1213
|
-
unit?: UnitEnum;
|
|
1214
|
-
fromHeight?: number;
|
|
1215
|
-
toHeight?: number;
|
|
1216
|
-
start?: number;
|
|
1217
|
-
count?: number;
|
|
1218
|
-
}): Promise<TransactionHistoryItem[]> {
|
|
1219
|
-
return getAddressHistory({
|
|
1220
|
-
address: this.cashaddr,
|
|
1221
|
-
provider: this.provider,
|
|
1222
|
-
unit,
|
|
1223
|
-
fromHeight,
|
|
1224
|
-
toHeight,
|
|
1225
|
-
start,
|
|
1226
|
-
count,
|
|
1227
|
-
});
|
|
969
|
+
throw Error("getRawHistory not implemented in BaseWallet");
|
|
1228
970
|
}
|
|
1229
971
|
|
|
1230
972
|
// gets last transaction of this wallet
|
|
@@ -1347,16 +1089,6 @@ export class BaseWallet implements WalletI {
|
|
|
1347
1089
|
|
|
1348
1090
|
//#endregion Funds
|
|
1349
1091
|
|
|
1350
|
-
// Convenience wrapper to verify interface
|
|
1351
|
-
public async verify(message: string, sig: string, publicKey?: Uint8Array) {
|
|
1352
|
-
return await new SignedMessage().verify(
|
|
1353
|
-
message,
|
|
1354
|
-
sig,
|
|
1355
|
-
this.cashaddr,
|
|
1356
|
-
publicKey
|
|
1357
|
-
);
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
1092
|
//#region Cashtokens
|
|
1361
1093
|
/**
|
|
1362
1094
|
* Create new cashtoken, both funglible and/or non-fungible (NFT)
|
|
@@ -1378,16 +1110,14 @@ export class BaseWallet implements WalletI {
|
|
|
1378
1110
|
sendRequests = [sendRequests];
|
|
1379
1111
|
}
|
|
1380
1112
|
|
|
1381
|
-
let utxos:
|
|
1382
|
-
if (options
|
|
1113
|
+
let utxos: Utxo[] = await this.getUtxos();
|
|
1114
|
+
if (options?.utxoIds) {
|
|
1383
1115
|
utxos = await checkUtxos(
|
|
1384
|
-
options.utxoIds.map((utxoId:
|
|
1116
|
+
options.utxoIds.map((utxoId: UtxoId | string) =>
|
|
1385
1117
|
typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId
|
|
1386
1118
|
),
|
|
1387
|
-
|
|
1119
|
+
utxos
|
|
1388
1120
|
);
|
|
1389
|
-
} else {
|
|
1390
|
-
utxos = await this.getAddressUtxos(this.cashaddr);
|
|
1391
1121
|
}
|
|
1392
1122
|
|
|
1393
1123
|
const genesisInputs = utxos.filter((val) => val.vout === 0 && !val.token);
|
|
@@ -1398,9 +1128,9 @@ export class BaseWallet implements WalletI {
|
|
|
1398
1128
|
}
|
|
1399
1129
|
|
|
1400
1130
|
const genesisSendRequest = new TokenSendRequest({
|
|
1401
|
-
cashaddr: genesisRequest.cashaddr || this.
|
|
1131
|
+
cashaddr: genesisRequest.cashaddr || this.getTokenDepositAddress(),
|
|
1402
1132
|
amount: genesisRequest.amount,
|
|
1403
|
-
value: genesisRequest.value ||
|
|
1133
|
+
value: genesisRequest.value || 1000n,
|
|
1404
1134
|
capability: genesisRequest.capability,
|
|
1405
1135
|
commitment: genesisRequest.commitment,
|
|
1406
1136
|
tokenId: genesisInputs[0].txid,
|
|
@@ -1442,7 +1172,7 @@ export class BaseWallet implements WalletI {
|
|
|
1442
1172
|
mintRequests = [mintRequests];
|
|
1443
1173
|
}
|
|
1444
1174
|
|
|
1445
|
-
const utxos = await this.
|
|
1175
|
+
const utxos = await this.getUtxos();
|
|
1446
1176
|
const nftUtxos = utxos.filter(
|
|
1447
1177
|
(val) =>
|
|
1448
1178
|
val.token?.tokenId === tokenId &&
|
|
@@ -1459,7 +1189,7 @@ export class BaseWallet implements WalletI {
|
|
|
1459
1189
|
: nftUtxos[0].token!.amount;
|
|
1460
1190
|
const safeNewAmount = newAmount < 0n ? 0n : newAmount;
|
|
1461
1191
|
const mintingInput = new TokenSendRequest({
|
|
1462
|
-
cashaddr:
|
|
1192
|
+
cashaddr: toTokenaddr(nftUtxos[0].address),
|
|
1463
1193
|
tokenId: tokenId,
|
|
1464
1194
|
capability: nftUtxos[0].token!.capability,
|
|
1465
1195
|
commitment: nftUtxos[0].token!.commitment,
|
|
@@ -1472,8 +1202,8 @@ export class BaseWallet implements WalletI {
|
|
|
1472
1202
|
...mintRequests.map(
|
|
1473
1203
|
(val) =>
|
|
1474
1204
|
new TokenSendRequest({
|
|
1475
|
-
cashaddr: val.cashaddr || this.
|
|
1476
|
-
amount:
|
|
1205
|
+
cashaddr: val.cashaddr || this.getTokenDepositAddress(),
|
|
1206
|
+
amount: 0n,
|
|
1477
1207
|
tokenId: tokenId,
|
|
1478
1208
|
value: val.value,
|
|
1479
1209
|
capability: val.capability,
|
|
@@ -1516,7 +1246,7 @@ export class BaseWallet implements WalletI {
|
|
|
1516
1246
|
throw Error(`Invalid tokenId supplied: ${burnRequest.tokenId}`);
|
|
1517
1247
|
}
|
|
1518
1248
|
|
|
1519
|
-
const utxos = await this.
|
|
1249
|
+
const utxos = await this.getUtxos();
|
|
1520
1250
|
const tokenUtxos = utxos.filter(
|
|
1521
1251
|
(val) =>
|
|
1522
1252
|
val.token?.tokenId === burnRequest.tokenId &&
|
|
@@ -1537,7 +1267,7 @@ export class BaseWallet implements WalletI {
|
|
|
1537
1267
|
fungibleBurnAmount = BigInt(fungibleBurnAmount);
|
|
1538
1268
|
const hasNFT = burnRequest.capability || burnRequest.commitment;
|
|
1539
1269
|
|
|
1540
|
-
let utxoIds:
|
|
1270
|
+
let utxoIds: Utxo[] = [];
|
|
1541
1271
|
let changeSendRequests: TokenSendRequest[];
|
|
1542
1272
|
if (hasNFT) {
|
|
1543
1273
|
// does not have FT tokens, let us destroy the token completely
|
|
@@ -1560,7 +1290,8 @@ export class BaseWallet implements WalletI {
|
|
|
1560
1290
|
const safeNewAmount = newAmount < 0n ? 0n : newAmount;
|
|
1561
1291
|
changeSendRequests = [
|
|
1562
1292
|
new TokenSendRequest({
|
|
1563
|
-
cashaddr:
|
|
1293
|
+
cashaddr:
|
|
1294
|
+
burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
|
|
1564
1295
|
tokenId: burnRequest.tokenId,
|
|
1565
1296
|
capability: burnRequest.capability,
|
|
1566
1297
|
commitment: burnRequest.commitment,
|
|
@@ -1590,10 +1321,11 @@ export class BaseWallet implements WalletI {
|
|
|
1590
1321
|
const safeNewAmount = newAmount < 0n ? 0n : newAmount;
|
|
1591
1322
|
changeSendRequests = [
|
|
1592
1323
|
new TokenSendRequest({
|
|
1593
|
-
cashaddr:
|
|
1324
|
+
cashaddr:
|
|
1325
|
+
burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
|
|
1594
1326
|
tokenId: burnRequest.tokenId,
|
|
1595
1327
|
amount: safeNewAmount,
|
|
1596
|
-
value: tokenUtxos.reduce((a, c) => a + c.satoshis,
|
|
1328
|
+
value: tokenUtxos.reduce((a, c) => a + c.satoshis, 0n),
|
|
1597
1329
|
}),
|
|
1598
1330
|
];
|
|
1599
1331
|
}
|
|
@@ -1613,10 +1345,10 @@ export class BaseWallet implements WalletI {
|
|
|
1613
1345
|
* getTokenUtxos Get unspent token outputs for the wallet
|
|
1614
1346
|
* will return utxos only for the specified token if `tokenId` provided
|
|
1615
1347
|
* @param {string?} tokenId tokenId (category) to filter utxos by, if not set will return utxos from all tokens
|
|
1616
|
-
* @returns {
|
|
1348
|
+
* @returns {Utxo[]} token utxos
|
|
1617
1349
|
*/
|
|
1618
|
-
public async getTokenUtxos(tokenId?: string): Promise<
|
|
1619
|
-
const utxos = await this.
|
|
1350
|
+
public async getTokenUtxos(tokenId?: string): Promise<Utxo[]> {
|
|
1351
|
+
const utxos = await this.getUtxos();
|
|
1620
1352
|
return utxos.filter((val) =>
|
|
1621
1353
|
tokenId ? val.token?.tokenId === tokenId : val.token
|
|
1622
1354
|
);
|
|
@@ -1687,38 +1419,31 @@ export class BaseWallet implements WalletI {
|
|
|
1687
1419
|
return result;
|
|
1688
1420
|
}
|
|
1689
1421
|
//#endregion Cashtokens
|
|
1690
|
-
}
|
|
1691
1422
|
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1423
|
+
public sign(
|
|
1424
|
+
message: string,
|
|
1425
|
+
privateKey: Uint8Array | undefined = undefined
|
|
1426
|
+
): SignedMessageResponseI {
|
|
1427
|
+
if (!privateKey) {
|
|
1428
|
+
throw new Error("Signing private key not provided");
|
|
1429
|
+
}
|
|
1430
|
+
return new SignedMessage().sign(message, privateKey);
|
|
1700
1431
|
}
|
|
1701
|
-
}
|
|
1702
1432
|
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1433
|
+
// Convenience wrapper to verify interface
|
|
1434
|
+
public verify(
|
|
1435
|
+
message: string,
|
|
1436
|
+
sig: string,
|
|
1437
|
+
address?: string,
|
|
1438
|
+
publicKey?: Uint8Array
|
|
1439
|
+
): VerifyMessageResponseI {
|
|
1440
|
+
if (!address && !publicKey) {
|
|
1441
|
+
throw new Error(
|
|
1442
|
+
"Either address or publicKey must be provided for verification"
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1713
1445
|
|
|
1714
|
-
|
|
1715
|
-
* Class to manage a regtest watch wallet.
|
|
1716
|
-
*/
|
|
1717
|
-
export class RegTestWatchWallet extends BaseWallet {
|
|
1718
|
-
static networkPrefix = CashAddressNetworkPrefix.regtest;
|
|
1719
|
-
static walletType = WalletTypeEnum.Watch;
|
|
1720
|
-
constructor() {
|
|
1721
|
-
super(NetworkType.Regtest);
|
|
1446
|
+
return new SignedMessage().verify(message, sig, address, publicKey);
|
|
1722
1447
|
}
|
|
1723
1448
|
}
|
|
1724
1449
|
|
|
@@ -1727,7 +1452,7 @@ export class RegTestWatchWallet extends BaseWallet {
|
|
|
1727
1452
|
* mainnet wallets on public servers if ALLOW_MAINNET_USER_WALLETS is set to false
|
|
1728
1453
|
* @param {BaseWallet} wallet a wallet
|
|
1729
1454
|
*/
|
|
1730
|
-
const _checkContextSafety = function (wallet: BaseWallet) {
|
|
1455
|
+
export const _checkContextSafety = function (wallet: BaseWallet) {
|
|
1731
1456
|
if (getRuntimePlatform() === "node") {
|
|
1732
1457
|
if (process.env.ALLOW_MAINNET_USER_WALLETS === `false`) {
|
|
1733
1458
|
if (wallet.network === NetworkType.Mainnet) {
|
|
@@ -1774,7 +1499,9 @@ export async function getNamedWalletId(
|
|
|
1774
1499
|
}
|
|
1775
1500
|
}
|
|
1776
1501
|
|
|
1777
|
-
function getStorageProvider(
|
|
1502
|
+
export function getStorageProvider(
|
|
1503
|
+
dbName: string
|
|
1504
|
+
): StorageProvider | undefined {
|
|
1778
1505
|
if (!BaseWallet.StorageProvider) {
|
|
1779
1506
|
return undefined;
|
|
1780
1507
|
}
|