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.
Files changed (195) hide show
  1. package/dist/index.html +1 -1
  2. package/dist/{mainnet-2.7.34.js → mainnet-3.0.0-next.1.js} +728 -708
  3. package/dist/module/cache/MemoryCache.d.ts +0 -1
  4. package/dist/module/cache/MemoryCache.d.ts.map +1 -1
  5. package/dist/module/cache/MemoryCache.js +5 -7
  6. package/dist/module/cache/MemoryCache.js.map +1 -1
  7. package/dist/module/cache/index.d.ts +1 -0
  8. package/dist/module/cache/index.d.ts.map +1 -1
  9. package/dist/module/cache/index.js +1 -0
  10. package/dist/module/cache/index.js.map +1 -1
  11. package/dist/module/cache/walletCache.d.ts +45 -0
  12. package/dist/module/cache/walletCache.d.ts.map +1 -0
  13. package/dist/module/cache/walletCache.js +140 -0
  14. package/dist/module/cache/walletCache.js.map +1 -0
  15. package/dist/module/chain.d.ts +1 -1
  16. package/dist/module/chain.js +1 -1
  17. package/dist/module/chain.js.map +1 -1
  18. package/dist/module/constant.d.ts +1 -1
  19. package/dist/module/constant.d.ts.map +1 -1
  20. package/dist/module/constant.js +1 -1
  21. package/dist/module/constant.js.map +1 -1
  22. package/dist/module/enum.d.ts +1 -7
  23. package/dist/module/enum.d.ts.map +1 -1
  24. package/dist/module/enum.js +0 -6
  25. package/dist/module/enum.js.map +1 -1
  26. package/dist/module/history/{electrumTransformer.d.ts → getHistory.d.ts} +3 -3
  27. package/dist/module/history/getHistory.d.ts.map +1 -0
  28. package/dist/module/history/{electrumTransformer.js → getHistory.js} +17 -14
  29. package/dist/module/history/getHistory.js.map +1 -0
  30. package/dist/module/index.d.ts +3 -1
  31. package/dist/module/index.d.ts.map +1 -1
  32. package/dist/module/index.js +3 -1
  33. package/dist/module/index.js.map +1 -1
  34. package/dist/module/interface.d.ts +7 -2
  35. package/dist/module/interface.d.ts.map +1 -1
  36. package/dist/module/interface.js.map +1 -1
  37. package/dist/module/message/interface.d.ts +2 -2
  38. package/dist/module/message/interface.d.ts.map +1 -1
  39. package/dist/module/message/interface.js +0 -3
  40. package/dist/module/message/interface.js.map +1 -1
  41. package/dist/module/message/signed.d.ts +5 -5
  42. package/dist/module/message/signed.d.ts.map +1 -1
  43. package/dist/module/message/signed.js +8 -8
  44. package/dist/module/message/signed.js.map +1 -1
  45. package/dist/module/network/ElectrumNetworkProvider.d.ts +2 -2
  46. package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
  47. package/dist/module/network/ElectrumNetworkProvider.js +3 -2
  48. package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
  49. package/dist/module/network/NetworkProvider.d.ts +2 -2
  50. package/dist/module/network/NetworkProvider.d.ts.map +1 -1
  51. package/dist/module/network/constant.js +4 -4
  52. package/dist/module/network/constant.js.map +1 -1
  53. package/dist/module/network/getRelayFeeCache.js +2 -2
  54. package/dist/module/network/getRelayFeeCache.js.map +1 -1
  55. package/dist/module/rate/ExchangeRate.d.ts +2 -1
  56. package/dist/module/rate/ExchangeRate.d.ts.map +1 -1
  57. package/dist/module/rate/ExchangeRate.js +4 -1
  58. package/dist/module/rate/ExchangeRate.js.map +1 -1
  59. package/dist/module/transaction/Wif.d.ts +25 -23
  60. package/dist/module/transaction/Wif.d.ts.map +1 -1
  61. package/dist/module/transaction/Wif.js +26 -25
  62. package/dist/module/transaction/Wif.js.map +1 -1
  63. package/dist/module/transaction/allocateFee.d.ts +3 -3
  64. package/dist/module/transaction/allocateFee.d.ts.map +1 -1
  65. package/dist/module/transaction/allocateFee.js +5 -6
  66. package/dist/module/transaction/allocateFee.js.map +1 -1
  67. package/dist/module/util/amountInSatoshi.d.ts +1 -1
  68. package/dist/module/util/amountInSatoshi.d.ts.map +1 -1
  69. package/dist/module/util/amountInSatoshi.js +3 -9
  70. package/dist/module/util/amountInSatoshi.js.map +1 -1
  71. package/dist/module/util/asSendRequestObject.d.ts.map +1 -1
  72. package/dist/module/util/asSendRequestObject.js +10 -7
  73. package/dist/module/util/asSendRequestObject.js.map +1 -1
  74. package/dist/module/util/checkUtxos.d.ts +2 -2
  75. package/dist/module/util/checkUtxos.d.ts.map +1 -1
  76. package/dist/module/util/checkUtxos.js +11 -12
  77. package/dist/module/util/checkUtxos.js.map +1 -1
  78. package/dist/module/util/convert.d.ts +3 -0
  79. package/dist/module/util/convert.d.ts.map +1 -1
  80. package/dist/module/util/convert.js +12 -0
  81. package/dist/module/util/convert.js.map +1 -1
  82. package/dist/module/util/deriveCashaddr.d.ts.map +1 -1
  83. package/dist/module/util/deriveCashaddr.js +6 -0
  84. package/dist/module/util/deriveCashaddr.js.map +1 -1
  85. package/dist/module/util/deriveNetwork.js +1 -1
  86. package/dist/module/util/deriveNetwork.js.map +1 -1
  87. package/dist/module/util/hd.d.ts +3 -0
  88. package/dist/module/util/hd.d.ts.map +1 -0
  89. package/dist/module/util/hd.js +11 -0
  90. package/dist/module/util/hd.js.map +1 -0
  91. package/dist/module/util/index.d.ts +3 -3
  92. package/dist/module/util/index.d.ts.map +1 -1
  93. package/dist/module/util/index.js +3 -3
  94. package/dist/module/util/index.js.map +1 -1
  95. package/dist/module/util/satoshiToAmount.d.ts +1 -1
  96. package/dist/module/util/satoshiToAmount.d.ts.map +1 -1
  97. package/dist/module/util/satoshiToAmount.js +3 -9
  98. package/dist/module/util/satoshiToAmount.js.map +1 -1
  99. package/dist/module/util/sumSendRequestAmounts.d.ts.map +1 -1
  100. package/dist/module/util/sumSendRequestAmounts.js +3 -4
  101. package/dist/module/util/sumSendRequestAmounts.js.map +1 -1
  102. package/dist/module/util/sumUtxoValue.d.ts +3 -3
  103. package/dist/module/util/sumUtxoValue.d.ts.map +1 -1
  104. package/dist/module/util/sumUtxoValue.js +2 -2
  105. package/dist/module/util/sumUtxoValue.js.map +1 -1
  106. package/dist/module/wallet/Base.d.ts +45 -103
  107. package/dist/module/wallet/Base.d.ts.map +1 -1
  108. package/dist/module/wallet/Base.js +99 -298
  109. package/dist/module/wallet/Base.js.map +1 -1
  110. package/dist/module/wallet/HDWallet.d.ts +164 -0
  111. package/dist/module/wallet/HDWallet.d.ts.map +1 -0
  112. package/dist/module/wallet/HDWallet.js +486 -0
  113. package/dist/module/wallet/HDWallet.js.map +1 -0
  114. package/dist/module/wallet/Util.js +1 -1
  115. package/dist/module/wallet/Util.js.map +1 -1
  116. package/dist/module/wallet/Watch.d.ts +151 -0
  117. package/dist/module/wallet/Watch.d.ts.map +1 -0
  118. package/dist/module/wallet/Watch.js +307 -0
  119. package/dist/module/wallet/Watch.js.map +1 -0
  120. package/dist/module/wallet/Wif.d.ts +23 -29
  121. package/dist/module/wallet/Wif.d.ts.map +1 -1
  122. package/dist/module/wallet/Wif.js +204 -267
  123. package/dist/module/wallet/Wif.js.map +1 -1
  124. package/dist/module/wallet/createWallet.d.ts +7 -1
  125. package/dist/module/wallet/createWallet.d.ts.map +1 -1
  126. package/dist/module/wallet/createWallet.js +26 -17
  127. package/dist/module/wallet/createWallet.js.map +1 -1
  128. package/dist/module/wallet/interface.d.ts +5 -6
  129. package/dist/module/wallet/interface.d.ts.map +1 -1
  130. package/dist/module/wallet/model.d.ts +15 -19
  131. package/dist/module/wallet/model.d.ts.map +1 -1
  132. package/dist/module/wallet/model.js +5 -25
  133. package/dist/module/wallet/model.js.map +1 -1
  134. package/dist/tsconfig.tsbuildinfo +1 -1
  135. package/package.json +1 -1
  136. package/src/cache/MemoryCache.ts +5 -5
  137. package/src/cache/index.ts +1 -0
  138. package/src/cache/walletCache.ts +239 -0
  139. package/src/chain.ts +1 -1
  140. package/src/constant.ts +1 -1
  141. package/src/enum.ts +0 -6
  142. package/src/history/{electrumTransformer.test.ts → getHistory.test.ts} +26 -53
  143. package/src/history/{electrumTransformer.ts → getHistory.ts} +31 -15
  144. package/src/index.ts +3 -1
  145. package/src/interface.ts +8 -2
  146. package/src/message/interface.ts +2 -28
  147. package/src/message/signed.test.ts +36 -48
  148. package/src/message/signed.ts +9 -12
  149. package/src/network/Connection.test.ts +3 -3
  150. package/src/network/ElectrumNetworkProvider.ts +5 -5
  151. package/src/network/NetworkProvider.ts +2 -2
  152. package/src/network/Rpc.test.ts +3 -4
  153. package/src/network/constant.ts +4 -4
  154. package/src/network/getRelayFeeCache.ts +2 -2
  155. package/src/rate/ExchangeRate.test.ts +2 -44
  156. package/src/rate/ExchangeRate.ts +5 -2
  157. package/src/transaction/Wif.ts +59 -52
  158. package/src/transaction/allocateFee.test.ts +110 -131
  159. package/src/transaction/allocateFee.ts +14 -15
  160. package/src/util/amountInSatoshi.test.ts +1 -9
  161. package/src/util/amountInSatoshi.ts +6 -10
  162. package/src/util/asSendRequestObject.ts +12 -7
  163. package/src/util/checkUtxos.ts +21 -26
  164. package/src/util/convert.ts +18 -0
  165. package/src/util/deriveCashaddr.ts +8 -0
  166. package/src/util/deriveNetwork.ts +1 -1
  167. package/src/util/derivePublicKeyHash.test.ts +0 -13
  168. package/src/util/hd.ts +16 -0
  169. package/src/util/index.ts +3 -7
  170. package/src/util/satoshiToAmount.test.ts +1 -1
  171. package/src/util/satoshiToAmount.ts +4 -10
  172. package/src/util/sumSendRequestAmounts.ts +3 -4
  173. package/src/util/sumUtxoValue.ts +7 -7
  174. package/src/wallet/Base.ts +147 -420
  175. package/src/wallet/Cashtokens.test.headless.js +11 -11
  176. package/src/wallet/Cashtokens.test.ts +36 -37
  177. package/src/wallet/HDWallet.test.ts +515 -0
  178. package/src/wallet/HDWallet.ts +764 -0
  179. package/src/wallet/Util.ts +1 -1
  180. package/src/wallet/Watch.ts +447 -0
  181. package/src/wallet/Wif.bip39.test.ts +1 -1
  182. package/src/wallet/Wif.test.ts +108 -133
  183. package/src/wallet/Wif.ts +258 -283
  184. package/src/wallet/createWallet.ts +28 -18
  185. package/src/wallet/interface.ts +5 -6
  186. package/src/wallet/model.test.ts +4 -7
  187. package/src/wallet/model.ts +19 -51
  188. package/dist/module/history/electrumTransformer.d.ts.map +0 -1
  189. package/dist/module/history/electrumTransformer.js.map +0 -1
  190. package/dist/module/util/balanceObjectFromSatoshi.d.ts +0 -8
  191. package/dist/module/util/balanceObjectFromSatoshi.d.ts.map +0 -1
  192. package/dist/module/util/balanceObjectFromSatoshi.js +0 -35
  193. package/dist/module/util/balanceObjectFromSatoshi.js.map +0 -1
  194. package/src/util/balanceObjectFromSatoshi.test.ts +0 -58
  195. package/src/util/balanceObjectFromSatoshi.ts +0 -52
@@ -1,22 +1,18 @@
1
- import { binToHex, CashAddressNetworkPrefix, CashAddressType, decodeCashAddress, encodeCashAddress, } from "@bitauth/libauth";
2
- import { DUST_UTXO_THRESHOLD } from "../constant.js";
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 } 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";
10
- import { balanceFromSatoshi, balanceResponseFromSatoshi, } from "../util/balanceObjectFromSatoshi.js";
6
+ import { buildEncodedTransaction, getFeeAmount, getFeeAmountSimple, getSuitableUtxos, placeholderPrivateKeyBin, } from "../transaction/Wif.js";
11
7
  import { checkUtxos } from "../util/checkUtxos.js";
12
- import { derivePrefix } from "../util/derivePublicKeyHash.js";
13
- import { amountInSatoshi, asSendRequestObject, deriveTokenaddr, getRuntimePlatform, hexToBin, sumTokenAmounts, sumUtxoValue, toTokenaddr, } from "../util/index.js";
14
- import { sanitizeUnit } from "../util/sanitizeUnit.js";
8
+ import { asSendRequestObject, getRuntimePlatform, sumTokenAmounts, sumUtxoValue, toTokenaddr, } from "../util/index.js";
15
9
  import { sumSendRequestAmounts } from "../util/sumSendRequestAmounts.js";
16
10
  import { FeePaidByEnum, WalletTypeEnum } from "./enum.js";
17
11
  import { fromUtxoId, OpReturnData, SendRequest, SendResponse, TokenSendRequest, } from "./model.js";
18
12
  import { Util } from "./Util.js";
19
- const placeholderPrivateKey = "0000000000000000000000000000000000000000000000000000000000000001";
13
+ import { SignedMessage } from "../message/signed.js";
14
+ export const placeholderCashAddr = "bitcoincash:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqfnhks603";
15
+ export const placeholderTokenAddr = "bitcoincash:zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqweyg7usz";
20
16
  /**
21
17
  * A class to hold features used by all wallets
22
18
  * @class BaseWallet
@@ -38,16 +34,7 @@ export class BaseWallet {
38
34
  }
39
35
  // Return wallet info
40
36
  getInfo() {
41
- return {
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
- };
37
+ throw Error("getInfo not implemented in BaseWallet");
51
38
  }
52
39
  slpSemiAware(value = true) {
53
40
  this._slpSemiAware = value;
@@ -69,7 +56,21 @@ export class BaseWallet {
69
56
  * @returns The deposit address as a string
70
57
  */
71
58
  getDepositAddress() {
72
- return this.cashaddr;
59
+ // return this.cashaddr;
60
+ throw Error("getDepositAddress not implemented in BaseWallet");
61
+ }
62
+ /**
63
+ * getChangeAddress - get a wallet change address
64
+ *
65
+ * a high-level function,
66
+ *
67
+ * @see {@link https://rest-unstable.mainnet.cash/api-docs/#/wallet/changeAddress|/wallet/change_address} for REST endpoint
68
+ *
69
+ * @returns The change address as a string
70
+ */
71
+ getChangeAddress() {
72
+ // return this.cashaddr;
73
+ throw Error("getChangeAddress not implemented in BaseWallet");
73
74
  }
74
75
  /**
75
76
  * getTokenDepositAddress - get a cashtoken aware wallet deposit address
@@ -77,7 +78,17 @@ export class BaseWallet {
77
78
  * @returns The cashtoken aware deposit address as a string
78
79
  */
79
80
  getTokenDepositAddress() {
80
- return this.tokenaddr;
81
+ // return this.tokenaddr;
82
+ throw Error("getTokenDepositAddress not implemented in BaseWallet");
83
+ }
84
+ /**
85
+ * getTokenDepositAddress - get a cashtoken aware wallet deposit address
86
+ *
87
+ * @returns The cashtoken aware deposit address as a string
88
+ */
89
+ getTokenChangeAddress() {
90
+ // return this.tokenaddr;
91
+ throw Error("getTokenDepositAddress not implemented in BaseWallet");
81
92
  }
82
93
  //#endregion Accessors
83
94
  //#region Constructors and Statics
@@ -95,19 +106,6 @@ export class BaseWallet {
95
106
  this.provider = this.getNetworkProvider(this.network);
96
107
  this.isTestnet = this.network === NetworkType.Mainnet ? false : true;
97
108
  }
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
109
  //#endregion Constructors
112
110
  /**
113
111
  * named (internal) get a named wallet from the database or create a new one.
@@ -142,7 +140,8 @@ export class BaseWallet {
142
140
  return recoveredWallet;
143
141
  }
144
142
  else {
145
- const wallet = await this.generate();
143
+ const wallet = await this.initialize();
144
+ wallet.name = name;
146
145
  await db.addWallet(wallet.name, wallet.toDbString());
147
146
  await db.close();
148
147
  return wallet;
@@ -214,7 +213,7 @@ export class BaseWallet {
214
213
  throw Error("No database was available or configured to store the named wallet.");
215
214
  }
216
215
  }
217
- async generate() {
216
+ async initialize() {
218
217
  return this;
219
218
  }
220
219
  //#region Serialization
@@ -248,45 +247,6 @@ export class BaseWallet {
248
247
  };
249
248
  return explorerUrlMap[this.network] + txId;
250
249
  }
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
250
  /**
291
251
  * named - create a named wallet
292
252
  *
@@ -326,62 +286,7 @@ export class BaseWallet {
326
286
  return new this().namedExists(name, dbName);
327
287
  }
328
288
  fromId(walletId) {
329
- const [walletType, networkGiven, arg1, arg2] = walletId.split(":");
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;
289
+ throw Error("fromId not implemented in BaseWallet");
385
290
  }
386
291
  //#region Funds
387
292
  /**
@@ -389,24 +294,15 @@ export class BaseWallet {
389
294
  *
390
295
  */
391
296
  async getUtxos() {
392
- if (!this.cashaddr) {
393
- throw Error("Attempted to get utxos without an address");
394
- }
395
- return await this.getAddressUtxos(this.cashaddr);
297
+ throw Error("getUtxos not implemented in BaseWallet");
396
298
  }
397
- // gets wallet balance in sats, bch and currency
398
- async getBalance(rawUnit, priceCache = true) {
399
- if (rawUnit) {
400
- const unit = sanitizeUnit(rawUnit);
401
- return await balanceFromSatoshi(await this.getBalanceFromProvider(), unit, priceCache);
402
- }
403
- else {
404
- return await balanceResponseFromSatoshi(await this.getBalanceFromProvider(), priceCache);
405
- }
299
+ // gets wallet balance in sats
300
+ async getBalance() {
301
+ return this.getBalanceFromProvider();
406
302
  }
407
303
  // Gets balance by summing value in all utxos in stats
408
304
  async getBalanceFromUtxos() {
409
- const utxos = (await this.getAddressUtxos(this.cashaddr)).filter((val) => val.token === undefined);
305
+ const utxos = (await this.getUtxos()).filter((val) => val.token === undefined);
410
306
  return sumUtxoValue(utxos);
411
307
  }
412
308
  // Gets balance from fulcrum
@@ -422,16 +318,7 @@ export class BaseWallet {
422
318
  return this.getBalanceFromUtxos();
423
319
  }
424
320
  async getAddressUtxos(address) {
425
- if (!address) {
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
- }
321
+ throw Error("getAddressUtxos not implemented in BaseWallet");
435
322
  }
436
323
  // watching for any transaction hash of this wallet
437
324
  async watchAddress(callback) {
@@ -449,39 +336,17 @@ export class BaseWallet {
449
336
  // can be cancelled by calling the function returned from this one
450
337
  async watchBalance(callback) {
451
338
  return this.provider.watchAddressStatus(this.getDepositAddress(), async (_status) => {
452
- const balance = (await this.getBalance());
339
+ const balance = await this.getBalanceFromProvider();
453
340
  callback(balance);
454
341
  });
455
342
  }
456
- // sets up a callback to be called upon wallet's BCH or USD balance change
457
- // if BCH balance does not change, the callback will be triggered every
458
- // @param `usdPriceRefreshInterval` milliseconds by polling for new BCH USD price
459
- // Since we want to be most sensitive to usd value change, we do not use the cached exchange rates
460
- // can be cancelled by calling the function returned from this one
461
- async watchBalanceUsd(callback, usdPriceRefreshInterval = 30000) {
462
- let usdPrice = -1;
463
- const _callback = async () => {
464
- const balance = (await this.getBalance(undefined, false));
465
- if (usdPrice !== balance.usd) {
466
- usdPrice = balance.usd;
467
- callback(balance);
468
- }
469
- };
470
- const watchCancel = await this.provider.watchAddressStatus(this.getDepositAddress(), _callback);
471
- const interval = setInterval(_callback, usdPriceRefreshInterval);
472
- return async () => {
473
- await watchCancel?.();
474
- clearInterval(interval);
475
- };
476
- }
477
343
  // waits for address balance to be greater than or equal to the target value
478
344
  // this call halts the execution
479
- async waitForBalance(value, rawUnit = UnitEnum.BCH) {
345
+ async waitForBalance(value) {
480
346
  return new Promise(async (resolve) => {
481
347
  let watchCancel;
482
348
  watchCancel = await this.watchBalance(async (balance) => {
483
- const satoshiBalance = await amountInSatoshi(value, rawUnit);
484
- if (balance.sat >= satoshiBalance) {
349
+ if (balance >= value) {
485
350
  await watchCancel?.();
486
351
  resolve(balance);
487
352
  }
@@ -517,12 +382,6 @@ export class BaseWallet {
517
382
  outputCount: 1,
518
383
  options: {},
519
384
  }) {
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
385
  if (params.options && params.options.slpSemiAware) {
527
386
  this._slpSemiAware = true;
528
387
  }
@@ -539,15 +398,14 @@ export class BaseWallet {
539
398
  utxos = await checkUtxos(params.options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId), this);
540
399
  }
541
400
  else {
542
- utxos = (await this.getAddressUtxos(this.cashaddr)).filter((utxo) => !utxo.token);
401
+ utxos = (await this.getUtxos()).filter((utxo) => !utxo.token);
543
402
  }
544
403
  // Get current height to assure recently mined coins are not spent.
545
404
  const bestHeight = await this.provider.getBlockHeight();
546
405
  // simulate outputs using the sender's address
547
406
  const sendRequest = new SendRequest({
548
- cashaddr: this.cashaddr,
549
- value: 100,
550
- unit: "sat",
407
+ cashaddr: placeholderCashAddr,
408
+ value: 100n,
551
409
  });
552
410
  const sendRequests = Array(params.outputCount)
553
411
  .fill(0)
@@ -557,15 +415,14 @@ export class BaseWallet {
557
415
  const fee = await getFeeAmountSimple({
558
416
  utxos: fundingUtxos,
559
417
  sendRequests: sendRequests,
560
- privateKey: params.privateKey ?? hexToBin(placeholderPrivateKey),
561
- sourceAddress: this.cashaddr,
418
+ sourceAddress: placeholderCashAddr,
562
419
  relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
563
420
  feePaidBy: feePaidBy,
564
421
  });
565
422
  const spendableAmount = sumUtxoValue(fundingUtxos);
566
423
  let result = spendableAmount - fee;
567
- if (result < 0) {
568
- result = 0;
424
+ if (result < 0n) {
425
+ result = 0n;
569
426
  }
570
427
  return { value: result, utxos: fundingUtxos };
571
428
  }
@@ -574,7 +431,7 @@ export class BaseWallet {
574
431
  options: {},
575
432
  }) {
576
433
  const { value: result } = await this._getMaxAmountToSend(params);
577
- return await balanceResponseFromSatoshi(result);
434
+ return result;
578
435
  }
579
436
  /**
580
437
  * send Send some amount to an address
@@ -595,7 +452,7 @@ export class BaseWallet {
595
452
  resp.explorerUrl = this.explorerUrl(resp.txId);
596
453
  if (options?.queryBalance === undefined ||
597
454
  options?.queryBalance === true) {
598
- resp.balance = (await this.getBalance());
455
+ resp.balance = await this.getBalance();
599
456
  }
600
457
  }
601
458
  else {
@@ -636,7 +493,6 @@ export class BaseWallet {
636
493
  const sendRequest = new SendRequest({
637
494
  cashaddr: cashaddr,
638
495
  value: maxSpendableAmount,
639
- unit: "sat",
640
496
  });
641
497
  const { encodedTransaction, tokenIds, sourceOutputs } = await this.encodeTransaction([sendRequest], true, options, privateKey);
642
498
  const resp = new SendResponse({});
@@ -648,7 +504,7 @@ export class BaseWallet {
648
504
  resp.explorerUrl = this.explorerUrl(resp.txId);
649
505
  if (options?.queryBalance === undefined ||
650
506
  options?.queryBalance === true) {
651
- resp.balance = (await this.getBalance());
507
+ resp.balance = await this.getBalance();
652
508
  }
653
509
  }
654
510
  else {
@@ -665,37 +521,31 @@ export class BaseWallet {
665
521
  */
666
522
  async encodeTransaction(requests, discardChange = false, options, privateKey) {
667
523
  let sendRequests = asSendRequestObject(requests);
668
- if (!privateKey && options?.buildUnsigned !== true) {
669
- throw new Error(`Missing private key`);
670
- }
671
524
  if (options && options.slpSemiAware) {
672
525
  this._slpSemiAware = true;
673
526
  }
674
527
  let feePaidBy;
675
- if (options && options.feePaidBy) {
528
+ if (options?.feePaidBy) {
676
529
  feePaidBy = options.feePaidBy;
677
530
  }
678
531
  else {
679
532
  feePaidBy = FeePaidByEnum.change;
680
533
  }
681
534
  let changeAddress;
682
- if (options && options.changeAddress) {
535
+ if (options?.changeAddress) {
683
536
  changeAddress = options.changeAddress;
684
537
  }
685
538
  else {
686
- changeAddress = this.cashaddr;
539
+ changeAddress = this.getChangeAddress();
687
540
  }
688
541
  let checkTokenQuantities = true;
689
- if (options && options.checkTokenQuantities === false) {
542
+ if (options?.checkTokenQuantities === false) {
690
543
  checkTokenQuantities = false;
691
544
  }
692
545
  // get inputs from options or query all inputs
693
- let utxos;
546
+ let utxos = await this.getUtxos();
694
547
  if (options && options.utxoIds) {
695
- utxos = await checkUtxos(options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId), this);
696
- }
697
- else {
698
- utxos = await this.getAddressUtxos(this.cashaddr);
548
+ utxos = await checkUtxos(options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId), utxos);
699
549
  }
700
550
  // filter out token utxos if there are no token requests
701
551
  if (checkTokenQuantities &&
@@ -745,7 +595,7 @@ export class BaseWallet {
745
595
  }
746
596
  if (change > 0) {
747
597
  outputs.push(new TokenSendRequest({
748
- cashaddr: toTokenaddr(changeAddress) || this.tokenaddr,
598
+ cashaddr: toTokenaddr(this.getChangeAddress()),
749
599
  amount: change,
750
600
  tokenId: tokenId,
751
601
  commitment: tokenOutputs[0].commitment,
@@ -769,33 +619,32 @@ export class BaseWallet {
769
619
  const feeEstimate = await getFeeAmountSimple({
770
620
  utxos: utxos,
771
621
  sendRequests: sendRequests,
772
- privateKey: privateKey ?? hexToBin(placeholderPrivateKey),
773
- sourceAddress: this.cashaddr,
622
+ sourceAddress: this.getDepositAddress(),
774
623
  relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
775
624
  feePaidBy: feePaidBy,
776
625
  });
777
- const fundingUtxos = await getSuitableUtxos(utxos, BigInt(spendAmount) + BigInt(Math.ceil(feeEstimate)), bestHeight, feePaidBy, sendRequests, options?.ensureUtxos || [], options?.tokenOperation);
626
+ const fundingUtxos = await getSuitableUtxos(utxos, spendAmount + feeEstimate, bestHeight, feePaidBy, sendRequests, options?.ensureUtxos || [], options?.tokenOperation);
778
627
  if (fundingUtxos.length === 0) {
779
628
  throw Error("The available inputs couldn't satisfy the request with fees");
780
629
  }
781
630
  const fee = await getFeeAmount({
782
631
  utxos: fundingUtxos,
783
632
  sendRequests: sendRequests,
784
- privateKey: privateKey ?? hexToBin(placeholderPrivateKey),
785
- sourceAddress: this.cashaddr,
633
+ sourceAddress: this.getDepositAddress(),
786
634
  relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
787
635
  feePaidBy: feePaidBy,
636
+ walletCache: this.walletCache,
788
637
  });
789
638
  const { encodedTransaction, sourceOutputs } = await buildEncodedTransaction({
790
639
  inputs: fundingUtxos,
791
640
  outputs: sendRequests,
792
- signingKey: privateKey ?? hexToBin(placeholderPrivateKey),
793
- sourceAddress: this.cashaddr,
641
+ signingKey: privateKey ?? placeholderPrivateKeyBin,
794
642
  fee,
795
643
  discardChange,
796
644
  feePaidBy,
797
645
  changeAddress,
798
646
  buildUnsigned: options?.buildUnsigned === true,
647
+ walletCache: this.walletCache,
799
648
  });
800
649
  const tokenIds = [
801
650
  ...fundingUtxos
@@ -817,32 +666,7 @@ export class BaseWallet {
817
666
  }
818
667
  // gets transaction history of this wallet
819
668
  async getRawHistory(fromHeight = 0, toHeight = -1) {
820
- return await this.provider.getHistory(this.cashaddr, fromHeight, toHeight);
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
- });
669
+ throw Error("getRawHistory not implemented in BaseWallet");
846
670
  }
847
671
  // gets last transaction of this wallet
848
672
  async getLastTransaction(confirmedOnly = false) {
@@ -933,10 +757,6 @@ export class BaseWallet {
933
757
  return this.provider.waitForBlock(height);
934
758
  }
935
759
  //#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
760
  //#region Cashtokens
941
761
  /**
942
762
  * Create new cashtoken, both funglible and/or non-fungible (NFT)
@@ -953,21 +773,18 @@ export class BaseWallet {
953
773
  if (!Array.isArray(sendRequests)) {
954
774
  sendRequests = [sendRequests];
955
775
  }
956
- let utxos;
957
- if (options && options.utxoIds) {
958
- utxos = await checkUtxos(options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId), this);
959
- }
960
- else {
961
- utxos = await this.getAddressUtxos(this.cashaddr);
776
+ let utxos = await this.getUtxos();
777
+ if (options?.utxoIds) {
778
+ utxos = await checkUtxos(options.utxoIds.map((utxoId) => typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId), utxos);
962
779
  }
963
780
  const genesisInputs = utxos.filter((val) => val.vout === 0 && !val.token);
964
781
  if (genesisInputs.length === 0) {
965
782
  throw new Error("No suitable inputs with vout=0 available for new token genesis");
966
783
  }
967
784
  const genesisSendRequest = new TokenSendRequest({
968
- cashaddr: genesisRequest.cashaddr || this.tokenaddr,
785
+ cashaddr: genesisRequest.cashaddr || this.getTokenDepositAddress(),
969
786
  amount: genesisRequest.amount,
970
- value: genesisRequest.value || 1000,
787
+ value: genesisRequest.value || 1000n,
971
788
  capability: genesisRequest.capability,
972
789
  commitment: genesisRequest.commitment,
973
790
  tokenId: genesisInputs[0].txid,
@@ -1000,7 +817,7 @@ export class BaseWallet {
1000
817
  if (!Array.isArray(mintRequests)) {
1001
818
  mintRequests = [mintRequests];
1002
819
  }
1003
- const utxos = await this.getAddressUtxos(this.cashaddr);
820
+ const utxos = await this.getUtxos();
1004
821
  const nftUtxos = utxos.filter((val) => val.token?.tokenId === tokenId &&
1005
822
  val.token?.capability === NFTCapability.minting);
1006
823
  if (!nftUtxos.length) {
@@ -1011,7 +828,7 @@ export class BaseWallet {
1011
828
  : nftUtxos[0].token.amount;
1012
829
  const safeNewAmount = newAmount < 0n ? 0n : newAmount;
1013
830
  const mintingInput = new TokenSendRequest({
1014
- cashaddr: this.tokenaddr,
831
+ cashaddr: toTokenaddr(nftUtxos[0].address),
1015
832
  tokenId: tokenId,
1016
833
  capability: nftUtxos[0].token.capability,
1017
834
  commitment: nftUtxos[0].token.commitment,
@@ -1021,8 +838,8 @@ export class BaseWallet {
1021
838
  return this.send([
1022
839
  mintingInput,
1023
840
  ...mintRequests.map((val) => new TokenSendRequest({
1024
- cashaddr: val.cashaddr || this.tokenaddr,
1025
- amount: 0,
841
+ cashaddr: val.cashaddr || this.getTokenDepositAddress(),
842
+ amount: 0n,
1026
843
  tokenId: tokenId,
1027
844
  value: val.value,
1028
845
  capability: val.capability,
@@ -1056,7 +873,7 @@ export class BaseWallet {
1056
873
  if (burnRequest.tokenId?.length !== 64) {
1057
874
  throw Error(`Invalid tokenId supplied: ${burnRequest.tokenId}`);
1058
875
  }
1059
- const utxos = await this.getAddressUtxos(this.cashaddr);
876
+ const utxos = await this.getUtxos();
1060
877
  const tokenUtxos = utxos.filter((val) => val.token?.tokenId === burnRequest.tokenId &&
1061
878
  val.token?.capability === burnRequest.capability &&
1062
879
  val.token?.commitment === burnRequest.commitment);
@@ -1090,7 +907,7 @@ export class BaseWallet {
1090
907
  const safeNewAmount = newAmount < 0n ? 0n : newAmount;
1091
908
  changeSendRequests = [
1092
909
  new TokenSendRequest({
1093
- cashaddr: burnRequest.cashaddr || this.tokenaddr,
910
+ cashaddr: burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
1094
911
  tokenId: burnRequest.tokenId,
1095
912
  capability: burnRequest.capability,
1096
913
  commitment: burnRequest.commitment,
@@ -1121,10 +938,10 @@ export class BaseWallet {
1121
938
  const safeNewAmount = newAmount < 0n ? 0n : newAmount;
1122
939
  changeSendRequests = [
1123
940
  new TokenSendRequest({
1124
- cashaddr: burnRequest.cashaddr || this.tokenaddr,
941
+ cashaddr: burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
1125
942
  tokenId: burnRequest.tokenId,
1126
943
  amount: safeNewAmount,
1127
- value: tokenUtxos.reduce((a, c) => a + c.satoshis, 0),
944
+ value: tokenUtxos.reduce((a, c) => a + c.satoshis, 0n),
1128
945
  }),
1129
946
  ];
1130
947
  }
@@ -1142,10 +959,10 @@ export class BaseWallet {
1142
959
  * getTokenUtxos Get unspent token outputs for the wallet
1143
960
  * will return utxos only for the specified token if `tokenId` provided
1144
961
  * @param {string?} tokenId tokenId (category) to filter utxos by, if not set will return utxos from all tokens
1145
- * @returns {UtxoI[]} token utxos
962
+ * @returns {Utxo[]} token utxos
1146
963
  */
1147
964
  async getTokenUtxos(tokenId) {
1148
- const utxos = await this.getAddressUtxos(this.cashaddr);
965
+ const utxos = await this.getUtxos();
1149
966
  return utxos.filter((val) => tokenId ? val.token?.tokenId === tokenId : val.token);
1150
967
  }
1151
968
  /**
@@ -1199,35 +1016,19 @@ export class BaseWallet {
1199
1016
  }
1200
1017
  return result;
1201
1018
  }
1202
- }
1203
- /**
1204
- * Class to manage a mainnet watch wallet.
1205
- */
1206
- export class WatchWallet extends BaseWallet {
1207
- static { this.networkPrefix = CashAddressNetworkPrefix.mainnet; }
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);
1019
+ //#endregion Cashtokens
1020
+ sign(message, privateKey = undefined) {
1021
+ if (!privateKey) {
1022
+ throw new Error("Signing private key not provided");
1023
+ }
1024
+ return new SignedMessage().sign(message, privateKey);
1221
1025
  }
1222
- }
1223
- /**
1224
- * Class to manage a regtest watch wallet.
1225
- */
1226
- export class RegTestWatchWallet extends BaseWallet {
1227
- static { this.networkPrefix = CashAddressNetworkPrefix.regtest; }
1228
- static { this.walletType = WalletTypeEnum.Watch; }
1229
- constructor() {
1230
- super(NetworkType.Regtest);
1026
+ // Convenience wrapper to verify interface
1027
+ verify(message, sig, address, publicKey) {
1028
+ if (!address && !publicKey) {
1029
+ throw new Error("Either address or publicKey must be provided for verification");
1030
+ }
1031
+ return new SignedMessage().verify(message, sig, address, publicKey);
1231
1032
  }
1232
1033
  }
1233
1034
  /**
@@ -1235,7 +1036,7 @@ export class RegTestWatchWallet extends BaseWallet {
1235
1036
  * mainnet wallets on public servers if ALLOW_MAINNET_USER_WALLETS is set to false
1236
1037
  * @param {BaseWallet} wallet a wallet
1237
1038
  */
1238
- const _checkContextSafety = function (wallet) {
1039
+ export const _checkContextSafety = function (wallet) {
1239
1040
  if (getRuntimePlatform() === "node") {
1240
1041
  if (process.env.ALLOW_MAINNET_USER_WALLETS === `false`) {
1241
1042
  if (wallet.network === NetworkType.Mainnet) {
@@ -1273,7 +1074,7 @@ export async function getNamedWalletId(name, dbName) {
1273
1074
  throw Error("No database was available or configured to store the named wallet.");
1274
1075
  }
1275
1076
  }
1276
- function getStorageProvider(dbName) {
1077
+ export function getStorageProvider(dbName) {
1277
1078
  if (!BaseWallet.StorageProvider) {
1278
1079
  return undefined;
1279
1080
  }