mainnet-js 2.7.33 → 3.0.0-next.0
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.33.js → mainnet-3.0.0-next.0.js} +718 -678
- 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 +39 -0
- package/dist/module/cache/walletCache.d.ts.map +1 -0
- package/dist/module/cache/walletCache.js +141 -0
- package/dist/module/cache/walletCache.js.map +1 -0
- 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} +47 -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 -1
- 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 +2 -1
- 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/transaction/Wif.d.ts +21 -19
- package/dist/module/transaction/Wif.d.ts.map +1 -1
- package/dist/module/transaction/Wif.js +18 -15
- package/dist/module/transaction/Wif.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/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 +1 -0
- package/dist/module/util/index.d.ts.map +1 -1
- package/dist/module/util/index.js +1 -0
- package/dist/module/util/index.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.map +1 -1
- package/dist/module/wallet/Base.d.ts +37 -93
- package/dist/module/wallet/Base.d.ts.map +1 -1
- package/dist/module/wallet/Base.js +83 -250
- 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/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 +3 -3
- package/dist/module/wallet/interface.d.ts.map +1 -1
- package/dist/module/wallet/model.d.ts +3 -3
- package/dist/module/wallet/model.d.ts.map +1 -1
- package/dist/module/wallet/model.js +2 -18
- 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 +252 -0
- package/src/history/{electrumTransformer.test.ts → getHistory.test.ts} +6 -19
- package/src/history/{electrumTransformer.ts → getHistory.ts} +63 -15
- package/src/index.ts +3 -1
- package/src/interface.ts +8 -1
- 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/ElectrumNetworkProvider.ts +4 -4
- package/src/network/NetworkProvider.ts +2 -2
- package/src/network/Rpc.test.ts +1 -1
- package/src/network/constant.ts +4 -4
- package/src/transaction/Wif.ts +41 -35
- package/src/util/checkUtxos.ts +21 -26
- 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 +1 -0
- package/src/util/sumUtxoValue.ts +5 -5
- package/src/wallet/Base.ts +123 -332
- package/src/wallet/HDWallet.test.ts +372 -0
- package/src/wallet/HDWallet.ts +764 -0
- package/src/wallet/Watch.ts +447 -0
- package/src/wallet/Wif.ts +258 -283
- package/src/wallet/createWallet.ts +28 -18
- package/src/wallet/interface.ts +3 -3
- package/src/wallet/model.test.ts +2 -2
- package/src/wallet/model.ts +6 -23
- package/dist/module/history/electrumTransformer.d.ts.map +0 -1
- package/dist/module/history/electrumTransformer.js.map +0 -1
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import { binToHex
|
|
2
|
-
import {
|
|
3
|
-
import { networkPrefixMap, NetworkType, prefixFromNetworkMap, UnitEnum, } from "../enum.js";
|
|
4
|
-
import { getAddressHistory } from "../history/electrumTransformer.js";
|
|
1
|
+
import { binToHex } from "@bitauth/libauth";
|
|
2
|
+
import { NetworkType, prefixFromNetworkMap, UnitEnum } from "../enum.js";
|
|
5
3
|
import { NFTCapability } from "../interface.js";
|
|
6
|
-
import { SignedMessage } from "../message/signed.js";
|
|
7
4
|
import { getNetworkProvider } from "../network/default.js";
|
|
8
5
|
import { getRelayFeeCache } from "../network/getRelayFeeCache.js";
|
|
9
|
-
import { buildEncodedTransaction, getFeeAmount, getFeeAmountSimple, getSuitableUtxos, } from "../transaction/Wif.js";
|
|
6
|
+
import { buildEncodedTransaction, getFeeAmount, getFeeAmountSimple, getSuitableUtxos, placeholderPrivateKeyBin, } from "../transaction/Wif.js";
|
|
10
7
|
import { balanceFromSatoshi, balanceResponseFromSatoshi, } from "../util/balanceObjectFromSatoshi.js";
|
|
11
8
|
import { checkUtxos } from "../util/checkUtxos.js";
|
|
12
|
-
import {
|
|
13
|
-
import { amountInSatoshi, asSendRequestObject, deriveTokenaddr, getRuntimePlatform, hexToBin, sumTokenAmounts, sumUtxoValue, toTokenaddr, } from "../util/index.js";
|
|
9
|
+
import { amountInSatoshi, asSendRequestObject, getRuntimePlatform, sumTokenAmounts, sumUtxoValue, toTokenaddr, } from "../util/index.js";
|
|
14
10
|
import { sanitizeUnit } from "../util/sanitizeUnit.js";
|
|
15
11
|
import { sumSendRequestAmounts } from "../util/sumSendRequestAmounts.js";
|
|
16
12
|
import { FeePaidByEnum, WalletTypeEnum } from "./enum.js";
|
|
17
13
|
import { fromUtxoId, OpReturnData, SendRequest, SendResponse, TokenSendRequest, } from "./model.js";
|
|
18
14
|
import { Util } from "./Util.js";
|
|
19
|
-
|
|
15
|
+
import { SignedMessage } from "../message/signed.js";
|
|
16
|
+
export const placeholderCashAddr = "bitcoincash:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqfnhks603";
|
|
17
|
+
export const placeholderTokenAddr = "bitcoincash:zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqweyg7usz";
|
|
20
18
|
/**
|
|
21
19
|
* A class to hold features used by all wallets
|
|
22
20
|
* @class BaseWallet
|
|
@@ -38,16 +36,7 @@ export class BaseWallet {
|
|
|
38
36
|
}
|
|
39
37
|
// Return wallet info
|
|
40
38
|
getInfo() {
|
|
41
|
-
|
|
42
|
-
cashaddr: this.cashaddr,
|
|
43
|
-
tokenaddr: this.tokenaddr,
|
|
44
|
-
isTestnet: this.isTestnet,
|
|
45
|
-
name: this.name,
|
|
46
|
-
network: this.network,
|
|
47
|
-
publicKeyHash: binToHex(this.publicKeyHash),
|
|
48
|
-
walletId: this.toString(),
|
|
49
|
-
walletDbEntry: this.toDbString(),
|
|
50
|
-
};
|
|
39
|
+
throw Error("getInfo not implemented in BaseWallet");
|
|
51
40
|
}
|
|
52
41
|
slpSemiAware(value = true) {
|
|
53
42
|
this._slpSemiAware = value;
|
|
@@ -69,7 +58,21 @@ export class BaseWallet {
|
|
|
69
58
|
* @returns The deposit address as a string
|
|
70
59
|
*/
|
|
71
60
|
getDepositAddress() {
|
|
72
|
-
return this.cashaddr;
|
|
61
|
+
// return this.cashaddr;
|
|
62
|
+
throw Error("getDepositAddress not implemented in BaseWallet");
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* getChangeAddress - get a wallet change address
|
|
66
|
+
*
|
|
67
|
+
* a high-level function,
|
|
68
|
+
*
|
|
69
|
+
* @see {@link https://rest-unstable.mainnet.cash/api-docs/#/wallet/changeAddress|/wallet/change_address} for REST endpoint
|
|
70
|
+
*
|
|
71
|
+
* @returns The change address as a string
|
|
72
|
+
*/
|
|
73
|
+
getChangeAddress() {
|
|
74
|
+
// return this.cashaddr;
|
|
75
|
+
throw Error("getChangeAddress not implemented in BaseWallet");
|
|
73
76
|
}
|
|
74
77
|
/**
|
|
75
78
|
* getTokenDepositAddress - get a cashtoken aware wallet deposit address
|
|
@@ -77,7 +80,17 @@ export class BaseWallet {
|
|
|
77
80
|
* @returns The cashtoken aware deposit address as a string
|
|
78
81
|
*/
|
|
79
82
|
getTokenDepositAddress() {
|
|
80
|
-
return this.tokenaddr;
|
|
83
|
+
// return this.tokenaddr;
|
|
84
|
+
throw Error("getTokenDepositAddress not implemented in BaseWallet");
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* getTokenDepositAddress - get a cashtoken aware wallet deposit address
|
|
88
|
+
*
|
|
89
|
+
* @returns The cashtoken aware deposit address as a string
|
|
90
|
+
*/
|
|
91
|
+
getTokenChangeAddress() {
|
|
92
|
+
// return this.tokenaddr;
|
|
93
|
+
throw Error("getTokenDepositAddress not implemented in BaseWallet");
|
|
81
94
|
}
|
|
82
95
|
//#endregion Accessors
|
|
83
96
|
//#region Constructors and Statics
|
|
@@ -95,19 +108,6 @@ export class BaseWallet {
|
|
|
95
108
|
this.provider = this.getNetworkProvider(this.network);
|
|
96
109
|
this.isTestnet = this.network === NetworkType.Mainnet ? false : true;
|
|
97
110
|
}
|
|
98
|
-
/**
|
|
99
|
-
* watchOnly - create a watch-only wallet
|
|
100
|
-
*
|
|
101
|
-
* such kind of wallet does not have a private key and is unable to spend any funds
|
|
102
|
-
* however it still allows to use many utility functions such as getting and watching balance, etc.
|
|
103
|
-
*
|
|
104
|
-
* @param address cashaddress, token aware cashaddress of a wallet
|
|
105
|
-
*
|
|
106
|
-
* @returns instantiated wallet
|
|
107
|
-
*/
|
|
108
|
-
static async watchOnly(address) {
|
|
109
|
-
return new this().watchOnly(address);
|
|
110
|
-
}
|
|
111
111
|
//#endregion Constructors
|
|
112
112
|
/**
|
|
113
113
|
* named (internal) get a named wallet from the database or create a new one.
|
|
@@ -142,7 +142,8 @@ export class BaseWallet {
|
|
|
142
142
|
return recoveredWallet;
|
|
143
143
|
}
|
|
144
144
|
else {
|
|
145
|
-
const wallet = await this.
|
|
145
|
+
const wallet = await this.initialize();
|
|
146
|
+
wallet.name = name;
|
|
146
147
|
await db.addWallet(wallet.name, wallet.toDbString());
|
|
147
148
|
await db.close();
|
|
148
149
|
return wallet;
|
|
@@ -214,7 +215,7 @@ export class BaseWallet {
|
|
|
214
215
|
throw Error("No database was available or configured to store the named wallet.");
|
|
215
216
|
}
|
|
216
217
|
}
|
|
217
|
-
async
|
|
218
|
+
async initialize() {
|
|
218
219
|
return this;
|
|
219
220
|
}
|
|
220
221
|
//#region Serialization
|
|
@@ -248,45 +249,6 @@ export class BaseWallet {
|
|
|
248
249
|
};
|
|
249
250
|
return explorerUrlMap[this.network] + txId;
|
|
250
251
|
}
|
|
251
|
-
// returns the public key hash for an address
|
|
252
|
-
getPublicKeyHash(hex = false) {
|
|
253
|
-
if (this.publicKeyHash) {
|
|
254
|
-
return hex ? binToHex(this.publicKeyHash) : this.publicKeyHash;
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
throw Error("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. ");
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* fromCashaddr - create a watch-only wallet in the network derived from the address
|
|
262
|
-
*
|
|
263
|
-
* such kind of wallet does not have a private key and is unable to spend any funds
|
|
264
|
-
* however it still allows to use many utility functions such as getting and watching balance, etc.
|
|
265
|
-
*
|
|
266
|
-
* @param address cashaddress of a wallet
|
|
267
|
-
*
|
|
268
|
-
* @returns instantiated wallet
|
|
269
|
-
*/
|
|
270
|
-
static async fromCashaddr(address) {
|
|
271
|
-
const prefix = derivePrefix(address);
|
|
272
|
-
const networkType = networkPrefixMap[prefix];
|
|
273
|
-
return new this(networkType).watchOnly(address);
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* fromTokenaddr - create a watch-only wallet in the network derived from the address
|
|
277
|
-
*
|
|
278
|
-
* such kind of wallet does not have a private key and is unable to spend any funds
|
|
279
|
-
* however it still allows to use many utility functions such as getting and watching balance, etc.
|
|
280
|
-
*
|
|
281
|
-
* @param address token aware cashaddress of a wallet
|
|
282
|
-
*
|
|
283
|
-
* @returns instantiated wallet
|
|
284
|
-
*/
|
|
285
|
-
static async fromTokenaddr(address) {
|
|
286
|
-
const prefix = derivePrefix(address);
|
|
287
|
-
const networkType = networkPrefixMap[prefix];
|
|
288
|
-
return new this(networkType).watchOnly(address);
|
|
289
|
-
}
|
|
290
252
|
/**
|
|
291
253
|
* named - create a named wallet
|
|
292
254
|
*
|
|
@@ -326,62 +288,7 @@ export class BaseWallet {
|
|
|
326
288
|
return new this().namedExists(name, dbName);
|
|
327
289
|
}
|
|
328
290
|
fromId(walletId) {
|
|
329
|
-
|
|
330
|
-
if (walletType !== WalletTypeEnum.Watch) {
|
|
331
|
-
throw Error(`fromId called on a ${walletType} wallet, expected a ${WalletTypeEnum.Watch} wallet`);
|
|
332
|
-
}
|
|
333
|
-
if (this.network != networkGiven) {
|
|
334
|
-
throw Error(`Network prefix ${networkGiven} to a ${this.network} wallet`);
|
|
335
|
-
}
|
|
336
|
-
if (arg2) {
|
|
337
|
-
return this.watchOnly(`${arg1}:${arg2}`);
|
|
338
|
-
}
|
|
339
|
-
return this.watchOnly(arg1);
|
|
340
|
-
}
|
|
341
|
-
// Initialize a watch only wallet from a cash addr
|
|
342
|
-
async watchOnly(address) {
|
|
343
|
-
// @ts-ignore
|
|
344
|
-
this.walletType = WalletTypeEnum.Watch;
|
|
345
|
-
const addressComponents = address.split(":");
|
|
346
|
-
let addressPrefix;
|
|
347
|
-
let addressBase;
|
|
348
|
-
if (addressComponents.length === 1) {
|
|
349
|
-
addressBase = addressComponents.shift();
|
|
350
|
-
addressPrefix = derivePrefix(addressBase);
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
addressPrefix = addressComponents.shift();
|
|
354
|
-
addressBase = addressComponents.shift();
|
|
355
|
-
if (addressPrefix in networkPrefixMap) {
|
|
356
|
-
if (networkPrefixMap[addressPrefix] !== this.network) {
|
|
357
|
-
throw Error(`a ${addressPrefix} address cannot be watched from a ${this.network} Wallet`);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
const prefixedAddress = `${addressPrefix}:${addressBase}`;
|
|
362
|
-
// check if a token aware address was provided
|
|
363
|
-
const addressData = decodeCashAddress(prefixedAddress);
|
|
364
|
-
if (typeof addressData === "string")
|
|
365
|
-
throw addressData;
|
|
366
|
-
// @ts-ignore
|
|
367
|
-
this.publicKeyHash = addressData.payload;
|
|
368
|
-
let nonTokenAwareType = addressData.type;
|
|
369
|
-
if (nonTokenAwareType == CashAddressType.p2pkhWithTokens)
|
|
370
|
-
nonTokenAwareType = CashAddressType.p2pkh;
|
|
371
|
-
if (nonTokenAwareType == CashAddressType.p2shWithTokens)
|
|
372
|
-
nonTokenAwareType = CashAddressType.p2sh;
|
|
373
|
-
if (nonTokenAwareType == CashAddressType.p2pkh)
|
|
374
|
-
// @ts-ignore
|
|
375
|
-
this.publicKeyHash = addressData.payload;
|
|
376
|
-
// @ts-ignore
|
|
377
|
-
this.cashaddr = encodeCashAddress({
|
|
378
|
-
prefix: addressData.prefix,
|
|
379
|
-
type: nonTokenAwareType,
|
|
380
|
-
payload: addressData.payload,
|
|
381
|
-
}).address;
|
|
382
|
-
// @ts-ignore
|
|
383
|
-
this.tokenaddr = deriveTokenaddr(addressData.payload, this.networkPrefix);
|
|
384
|
-
return this;
|
|
291
|
+
throw Error("fromId not implemented in BaseWallet");
|
|
385
292
|
}
|
|
386
293
|
//#region Funds
|
|
387
294
|
/**
|
|
@@ -389,10 +296,7 @@ export class BaseWallet {
|
|
|
389
296
|
*
|
|
390
297
|
*/
|
|
391
298
|
async getUtxos() {
|
|
392
|
-
|
|
393
|
-
throw Error("Attempted to get utxos without an address");
|
|
394
|
-
}
|
|
395
|
-
return await this.getAddressUtxos(this.cashaddr);
|
|
299
|
+
throw Error("getUtxos not implemented in BaseWallet");
|
|
396
300
|
}
|
|
397
301
|
// gets wallet balance in sats, bch and currency
|
|
398
302
|
async getBalance(rawUnit, priceCache = true) {
|
|
@@ -406,7 +310,7 @@ export class BaseWallet {
|
|
|
406
310
|
}
|
|
407
311
|
// Gets balance by summing value in all utxos in stats
|
|
408
312
|
async getBalanceFromUtxos() {
|
|
409
|
-
const utxos = (await this.
|
|
313
|
+
const utxos = (await this.getUtxos()).filter((val) => val.token === undefined);
|
|
410
314
|
return sumUtxoValue(utxos);
|
|
411
315
|
}
|
|
412
316
|
// Gets balance from fulcrum
|
|
@@ -422,16 +326,7 @@ export class BaseWallet {
|
|
|
422
326
|
return this.getBalanceFromUtxos();
|
|
423
327
|
}
|
|
424
328
|
async getAddressUtxos(address) {
|
|
425
|
-
|
|
426
|
-
address = this.cashaddr;
|
|
427
|
-
}
|
|
428
|
-
if (this._slpSemiAware) {
|
|
429
|
-
const bchUtxos = await this.provider.getUtxos(address);
|
|
430
|
-
return bchUtxos.filter((bchutxo) => bchutxo.satoshis > DUST_UTXO_THRESHOLD);
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
return await this.provider.getUtxos(address);
|
|
434
|
-
}
|
|
329
|
+
throw Error("getAddressUtxos not implemented in BaseWallet");
|
|
435
330
|
}
|
|
436
331
|
// watching for any transaction hash of this wallet
|
|
437
332
|
async watchAddress(callback) {
|
|
@@ -517,12 +412,6 @@ export class BaseWallet {
|
|
|
517
412
|
outputCount: 1,
|
|
518
413
|
options: {},
|
|
519
414
|
}) {
|
|
520
|
-
if (!params.privateKey && params.options?.buildUnsigned !== true) {
|
|
521
|
-
throw Error("Couldn't get network or private key for wallet.");
|
|
522
|
-
}
|
|
523
|
-
if (!this.cashaddr) {
|
|
524
|
-
throw Error("attempted to send without a cashaddr");
|
|
525
|
-
}
|
|
526
415
|
if (params.options && params.options.slpSemiAware) {
|
|
527
416
|
this._slpSemiAware = true;
|
|
528
417
|
}
|
|
@@ -539,13 +428,13 @@ export class BaseWallet {
|
|
|
539
428
|
utxos = await checkUtxos(params.options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId), this);
|
|
540
429
|
}
|
|
541
430
|
else {
|
|
542
|
-
utxos = (await this.
|
|
431
|
+
utxos = (await this.getUtxos()).filter((utxo) => !utxo.token);
|
|
543
432
|
}
|
|
544
433
|
// Get current height to assure recently mined coins are not spent.
|
|
545
434
|
const bestHeight = await this.provider.getBlockHeight();
|
|
546
435
|
// simulate outputs using the sender's address
|
|
547
436
|
const sendRequest = new SendRequest({
|
|
548
|
-
cashaddr:
|
|
437
|
+
cashaddr: placeholderCashAddr,
|
|
549
438
|
value: 100,
|
|
550
439
|
unit: "sat",
|
|
551
440
|
});
|
|
@@ -557,8 +446,7 @@ export class BaseWallet {
|
|
|
557
446
|
const fee = await getFeeAmountSimple({
|
|
558
447
|
utxos: fundingUtxos,
|
|
559
448
|
sendRequests: sendRequests,
|
|
560
|
-
|
|
561
|
-
sourceAddress: this.cashaddr,
|
|
449
|
+
sourceAddress: placeholderCashAddr,
|
|
562
450
|
relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
|
|
563
451
|
feePaidBy: feePaidBy,
|
|
564
452
|
});
|
|
@@ -665,37 +553,31 @@ export class BaseWallet {
|
|
|
665
553
|
*/
|
|
666
554
|
async encodeTransaction(requests, discardChange = false, options, privateKey) {
|
|
667
555
|
let sendRequests = asSendRequestObject(requests);
|
|
668
|
-
if (!privateKey && options?.buildUnsigned !== true) {
|
|
669
|
-
throw new Error(`Missing private key`);
|
|
670
|
-
}
|
|
671
556
|
if (options && options.slpSemiAware) {
|
|
672
557
|
this._slpSemiAware = true;
|
|
673
558
|
}
|
|
674
559
|
let feePaidBy;
|
|
675
|
-
if (options
|
|
560
|
+
if (options?.feePaidBy) {
|
|
676
561
|
feePaidBy = options.feePaidBy;
|
|
677
562
|
}
|
|
678
563
|
else {
|
|
679
564
|
feePaidBy = FeePaidByEnum.change;
|
|
680
565
|
}
|
|
681
566
|
let changeAddress;
|
|
682
|
-
if (options
|
|
567
|
+
if (options?.changeAddress) {
|
|
683
568
|
changeAddress = options.changeAddress;
|
|
684
569
|
}
|
|
685
570
|
else {
|
|
686
|
-
changeAddress = this.
|
|
571
|
+
changeAddress = this.getChangeAddress();
|
|
687
572
|
}
|
|
688
573
|
let checkTokenQuantities = true;
|
|
689
|
-
if (options
|
|
574
|
+
if (options?.checkTokenQuantities === false) {
|
|
690
575
|
checkTokenQuantities = false;
|
|
691
576
|
}
|
|
692
577
|
// get inputs from options or query all inputs
|
|
693
|
-
let utxos;
|
|
578
|
+
let utxos = await this.getUtxos();
|
|
694
579
|
if (options && options.utxoIds) {
|
|
695
|
-
utxos = await checkUtxos(options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId),
|
|
696
|
-
}
|
|
697
|
-
else {
|
|
698
|
-
utxos = await this.getAddressUtxos(this.cashaddr);
|
|
580
|
+
utxos = await checkUtxos(options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId), utxos);
|
|
699
581
|
}
|
|
700
582
|
// filter out token utxos if there are no token requests
|
|
701
583
|
if (checkTokenQuantities &&
|
|
@@ -745,7 +627,7 @@ export class BaseWallet {
|
|
|
745
627
|
}
|
|
746
628
|
if (change > 0) {
|
|
747
629
|
outputs.push(new TokenSendRequest({
|
|
748
|
-
cashaddr: toTokenaddr(
|
|
630
|
+
cashaddr: toTokenaddr(this.getChangeAddress()),
|
|
749
631
|
amount: change,
|
|
750
632
|
tokenId: tokenId,
|
|
751
633
|
commitment: tokenOutputs[0].commitment,
|
|
@@ -769,8 +651,7 @@ export class BaseWallet {
|
|
|
769
651
|
const feeEstimate = await getFeeAmountSimple({
|
|
770
652
|
utxos: utxos,
|
|
771
653
|
sendRequests: sendRequests,
|
|
772
|
-
|
|
773
|
-
sourceAddress: this.cashaddr,
|
|
654
|
+
sourceAddress: this.getDepositAddress(),
|
|
774
655
|
relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
|
|
775
656
|
feePaidBy: feePaidBy,
|
|
776
657
|
});
|
|
@@ -781,21 +662,21 @@ export class BaseWallet {
|
|
|
781
662
|
const fee = await getFeeAmount({
|
|
782
663
|
utxos: fundingUtxos,
|
|
783
664
|
sendRequests: sendRequests,
|
|
784
|
-
|
|
785
|
-
sourceAddress: this.cashaddr,
|
|
665
|
+
sourceAddress: this.getDepositAddress(),
|
|
786
666
|
relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
|
|
787
667
|
feePaidBy: feePaidBy,
|
|
668
|
+
walletCache: this.walletCache,
|
|
788
669
|
});
|
|
789
670
|
const { encodedTransaction, sourceOutputs } = await buildEncodedTransaction({
|
|
790
671
|
inputs: fundingUtxos,
|
|
791
672
|
outputs: sendRequests,
|
|
792
|
-
signingKey: privateKey ??
|
|
793
|
-
sourceAddress: this.cashaddr,
|
|
673
|
+
signingKey: privateKey ?? placeholderPrivateKeyBin,
|
|
794
674
|
fee,
|
|
795
675
|
discardChange,
|
|
796
676
|
feePaidBy,
|
|
797
677
|
changeAddress,
|
|
798
678
|
buildUnsigned: options?.buildUnsigned === true,
|
|
679
|
+
walletCache: this.walletCache,
|
|
799
680
|
});
|
|
800
681
|
const tokenIds = [
|
|
801
682
|
...fundingUtxos
|
|
@@ -817,32 +698,7 @@ export class BaseWallet {
|
|
|
817
698
|
}
|
|
818
699
|
// gets transaction history of this wallet
|
|
819
700
|
async getRawHistory(fromHeight = 0, toHeight = -1) {
|
|
820
|
-
|
|
821
|
-
}
|
|
822
|
-
/**
|
|
823
|
-
* getHistory gets transaction history of this wallet with most data decoded and ready to present to user
|
|
824
|
-
* @note balance calculations are valid only if querying to the blockchain tip (`toHeight` === -1, `count` === -1)
|
|
825
|
-
* @note this method is heavy on network calls, if invoked in browser use of cache is advised, @see `Config.UseLocalStorageCache`
|
|
826
|
-
* @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)
|
|
827
|
-
*
|
|
828
|
-
* @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
|
|
829
|
-
* @param fromHeight optional, if set, history will be limited. Default 0
|
|
830
|
-
* @param toHeight optional, if set, history will be limited. Default -1, meaning that all history items will be returned, including mempool
|
|
831
|
-
* @param start optional, if set, the result set will be paginated with offset `start`
|
|
832
|
-
* @param count optional, if set, the result set will be paginated with `count`. Default -1, meaning that all history items will be returned
|
|
833
|
-
*
|
|
834
|
-
* @returns an array of transaction history items, with input values and addresses encoded in cashaddress format. @see `TransactionHistoryItem` type
|
|
835
|
-
*/
|
|
836
|
-
async getHistory({ unit = "sat", fromHeight = 0, toHeight = -1, start = 0, count = -1, }) {
|
|
837
|
-
return getAddressHistory({
|
|
838
|
-
address: this.cashaddr,
|
|
839
|
-
provider: this.provider,
|
|
840
|
-
unit,
|
|
841
|
-
fromHeight,
|
|
842
|
-
toHeight,
|
|
843
|
-
start,
|
|
844
|
-
count,
|
|
845
|
-
});
|
|
701
|
+
throw Error("getRawHistory not implemented in BaseWallet");
|
|
846
702
|
}
|
|
847
703
|
// gets last transaction of this wallet
|
|
848
704
|
async getLastTransaction(confirmedOnly = false) {
|
|
@@ -933,10 +789,6 @@ export class BaseWallet {
|
|
|
933
789
|
return this.provider.waitForBlock(height);
|
|
934
790
|
}
|
|
935
791
|
//#endregion Funds
|
|
936
|
-
// Convenience wrapper to verify interface
|
|
937
|
-
async verify(message, sig, publicKey) {
|
|
938
|
-
return await new SignedMessage().verify(message, sig, this.cashaddr, publicKey);
|
|
939
|
-
}
|
|
940
792
|
//#region Cashtokens
|
|
941
793
|
/**
|
|
942
794
|
* Create new cashtoken, both funglible and/or non-fungible (NFT)
|
|
@@ -953,19 +805,16 @@ export class BaseWallet {
|
|
|
953
805
|
if (!Array.isArray(sendRequests)) {
|
|
954
806
|
sendRequests = [sendRequests];
|
|
955
807
|
}
|
|
956
|
-
let utxos;
|
|
957
|
-
if (options
|
|
958
|
-
utxos = await checkUtxos(options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId),
|
|
959
|
-
}
|
|
960
|
-
else {
|
|
961
|
-
utxos = await this.getAddressUtxos(this.cashaddr);
|
|
808
|
+
let utxos = await this.getUtxos();
|
|
809
|
+
if (options?.utxoIds) {
|
|
810
|
+
utxos = await checkUtxos(options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId), utxos);
|
|
962
811
|
}
|
|
963
812
|
const genesisInputs = utxos.filter((val) => val.vout === 0 && !val.token);
|
|
964
813
|
if (genesisInputs.length === 0) {
|
|
965
814
|
throw new Error("No suitable inputs with vout=0 available for new token genesis");
|
|
966
815
|
}
|
|
967
816
|
const genesisSendRequest = new TokenSendRequest({
|
|
968
|
-
cashaddr: genesisRequest.cashaddr || this.
|
|
817
|
+
cashaddr: genesisRequest.cashaddr || this.getTokenDepositAddress(),
|
|
969
818
|
amount: genesisRequest.amount,
|
|
970
819
|
value: genesisRequest.value || 1000,
|
|
971
820
|
capability: genesisRequest.capability,
|
|
@@ -1000,7 +849,7 @@ export class BaseWallet {
|
|
|
1000
849
|
if (!Array.isArray(mintRequests)) {
|
|
1001
850
|
mintRequests = [mintRequests];
|
|
1002
851
|
}
|
|
1003
|
-
const utxos = await this.
|
|
852
|
+
const utxos = await this.getUtxos();
|
|
1004
853
|
const nftUtxos = utxos.filter((val) => val.token?.tokenId === tokenId &&
|
|
1005
854
|
val.token?.capability === NFTCapability.minting);
|
|
1006
855
|
if (!nftUtxos.length) {
|
|
@@ -1011,7 +860,7 @@ export class BaseWallet {
|
|
|
1011
860
|
: nftUtxos[0].token.amount;
|
|
1012
861
|
const safeNewAmount = newAmount < 0n ? 0n : newAmount;
|
|
1013
862
|
const mintingInput = new TokenSendRequest({
|
|
1014
|
-
cashaddr:
|
|
863
|
+
cashaddr: toTokenaddr(nftUtxos[0].address),
|
|
1015
864
|
tokenId: tokenId,
|
|
1016
865
|
capability: nftUtxos[0].token.capability,
|
|
1017
866
|
commitment: nftUtxos[0].token.commitment,
|
|
@@ -1021,7 +870,7 @@ export class BaseWallet {
|
|
|
1021
870
|
return this.send([
|
|
1022
871
|
mintingInput,
|
|
1023
872
|
...mintRequests.map((val) => new TokenSendRequest({
|
|
1024
|
-
cashaddr: val.cashaddr || this.
|
|
873
|
+
cashaddr: val.cashaddr || this.getTokenDepositAddress(),
|
|
1025
874
|
amount: 0,
|
|
1026
875
|
tokenId: tokenId,
|
|
1027
876
|
value: val.value,
|
|
@@ -1056,7 +905,7 @@ export class BaseWallet {
|
|
|
1056
905
|
if (burnRequest.tokenId?.length !== 64) {
|
|
1057
906
|
throw Error(`Invalid tokenId supplied: ${burnRequest.tokenId}`);
|
|
1058
907
|
}
|
|
1059
|
-
const utxos = await this.
|
|
908
|
+
const utxos = await this.getUtxos();
|
|
1060
909
|
const tokenUtxos = utxos.filter((val) => val.token?.tokenId === burnRequest.tokenId &&
|
|
1061
910
|
val.token?.capability === burnRequest.capability &&
|
|
1062
911
|
val.token?.commitment === burnRequest.commitment);
|
|
@@ -1090,7 +939,7 @@ export class BaseWallet {
|
|
|
1090
939
|
const safeNewAmount = newAmount < 0n ? 0n : newAmount;
|
|
1091
940
|
changeSendRequests = [
|
|
1092
941
|
new TokenSendRequest({
|
|
1093
|
-
cashaddr: burnRequest.cashaddr || this.
|
|
942
|
+
cashaddr: burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
|
|
1094
943
|
tokenId: burnRequest.tokenId,
|
|
1095
944
|
capability: burnRequest.capability,
|
|
1096
945
|
commitment: burnRequest.commitment,
|
|
@@ -1121,7 +970,7 @@ export class BaseWallet {
|
|
|
1121
970
|
const safeNewAmount = newAmount < 0n ? 0n : newAmount;
|
|
1122
971
|
changeSendRequests = [
|
|
1123
972
|
new TokenSendRequest({
|
|
1124
|
-
cashaddr: burnRequest.cashaddr || this.
|
|
973
|
+
cashaddr: burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
|
|
1125
974
|
tokenId: burnRequest.tokenId,
|
|
1126
975
|
amount: safeNewAmount,
|
|
1127
976
|
value: tokenUtxos.reduce((a, c) => a + c.satoshis, 0),
|
|
@@ -1142,10 +991,10 @@ export class BaseWallet {
|
|
|
1142
991
|
* getTokenUtxos Get unspent token outputs for the wallet
|
|
1143
992
|
* will return utxos only for the specified token if `tokenId` provided
|
|
1144
993
|
* @param {string?} tokenId tokenId (category) to filter utxos by, if not set will return utxos from all tokens
|
|
1145
|
-
* @returns {
|
|
994
|
+
* @returns {Utxo[]} token utxos
|
|
1146
995
|
*/
|
|
1147
996
|
async getTokenUtxos(tokenId) {
|
|
1148
|
-
const utxos = await this.
|
|
997
|
+
const utxos = await this.getUtxos();
|
|
1149
998
|
return utxos.filter((val) => tokenId ? val.token?.tokenId === tokenId : val.token);
|
|
1150
999
|
}
|
|
1151
1000
|
/**
|
|
@@ -1199,35 +1048,19 @@ export class BaseWallet {
|
|
|
1199
1048
|
}
|
|
1200
1049
|
return result;
|
|
1201
1050
|
}
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
static { this.walletType = WalletTypeEnum.Watch; }
|
|
1209
|
-
constructor() {
|
|
1210
|
-
super(NetworkType.Mainnet);
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
/**
|
|
1214
|
-
* Class to manage a testnet watch wallet.
|
|
1215
|
-
*/
|
|
1216
|
-
export class TestNetWatchWallet extends BaseWallet {
|
|
1217
|
-
static { this.networkPrefix = CashAddressNetworkPrefix.testnet; }
|
|
1218
|
-
static { this.walletType = WalletTypeEnum.Watch; }
|
|
1219
|
-
constructor() {
|
|
1220
|
-
super(NetworkType.Testnet);
|
|
1051
|
+
//#endregion Cashtokens
|
|
1052
|
+
sign(message, privateKey = undefined) {
|
|
1053
|
+
if (!privateKey) {
|
|
1054
|
+
throw new Error("Signing private key not provided");
|
|
1055
|
+
}
|
|
1056
|
+
return new SignedMessage().sign(message, privateKey);
|
|
1221
1057
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
static { this.walletType = WalletTypeEnum.Watch; }
|
|
1229
|
-
constructor() {
|
|
1230
|
-
super(NetworkType.Regtest);
|
|
1058
|
+
// Convenience wrapper to verify interface
|
|
1059
|
+
verify(message, sig, address, publicKey) {
|
|
1060
|
+
if (!address && !publicKey) {
|
|
1061
|
+
throw new Error("Either address or publicKey must be provided for verification");
|
|
1062
|
+
}
|
|
1063
|
+
return new SignedMessage().verify(message, sig, address, publicKey);
|
|
1231
1064
|
}
|
|
1232
1065
|
}
|
|
1233
1066
|
/**
|
|
@@ -1235,7 +1068,7 @@ export class RegTestWatchWallet extends BaseWallet {
|
|
|
1235
1068
|
* mainnet wallets on public servers if ALLOW_MAINNET_USER_WALLETS is set to false
|
|
1236
1069
|
* @param {BaseWallet} wallet a wallet
|
|
1237
1070
|
*/
|
|
1238
|
-
const _checkContextSafety = function (wallet) {
|
|
1071
|
+
export const _checkContextSafety = function (wallet) {
|
|
1239
1072
|
if (getRuntimePlatform() === "node") {
|
|
1240
1073
|
if (process.env.ALLOW_MAINNET_USER_WALLETS === `false`) {
|
|
1241
1074
|
if (wallet.network === NetworkType.Mainnet) {
|
|
@@ -1273,7 +1106,7 @@ export async function getNamedWalletId(name, dbName) {
|
|
|
1273
1106
|
throw Error("No database was available or configured to store the named wallet.");
|
|
1274
1107
|
}
|
|
1275
1108
|
}
|
|
1276
|
-
function getStorageProvider(dbName) {
|
|
1109
|
+
export function getStorageProvider(dbName) {
|
|
1277
1110
|
if (!BaseWallet.StorageProvider) {
|
|
1278
1111
|
return undefined;
|
|
1279
1112
|
}
|