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,12 @@
1
- import {
2
- binToHex,
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
- networkPrefixMap,
12
- NetworkType,
13
- prefixFromNetworkMap,
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 { Wallet } from "./Wif.js";
52
+ import { SignedMessage } from "../message/signed.js";
72
53
 
73
- const placeholderPrivateKey =
74
- "0000000000000000000000000000000000000000000000000000000000000001";
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
- return {
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.generate();
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 generate(): Promise<this> {
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 Wallet>(
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 Wallet>(
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
- const [walletType, networkGiven, arg1, arg2]: string[] =
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
- if (!this.cashaddr) {
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, bch and currency
544
- public async getBalance(
545
- rawUnit?: string,
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<number> {
565
- const utxos = (await this.getAddressUtxos(this.cashaddr)).filter(
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<number> {
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<UtxoI[]> {
586
- if (!address) {
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: BalanceResponse) => void
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 = (await this.getBalance()) as BalanceResponse;
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
- async (balance: BalanceResponse) => {
685
- const satoshiBalance = await amountInSatoshi(value, rawUnit);
686
- if (balance.sat! >= satoshiBalance) {
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: number; utxos: UtxoI[] }> {
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: UtxoI[];
555
+ let utxos: Utxo[];
764
556
  if (params.options && params.options.utxoIds) {
765
557
  utxos = await checkUtxos(
766
- params.options.utxoIds.map((utxoId: UtxoI | string) =>
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.getAddressUtxos(this.cashaddr)).filter(
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: this.cashaddr,
783
- value: 100,
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
- privateKey: params.privateKey ?? hexToBin(placeholderPrivateKey),
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 < 0) {
810
- result = 0;
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<BalanceResponse> {
612
+ ): Promise<bigint> {
825
613
  const { value: result } = await this._getMaxAmountToSend(params);
826
614
 
827
- return await balanceResponseFromSatoshi(result);
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 = (await this.getBalance()) as BalanceResponse;
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 = (await this.getBalance()) as BalanceResponse;
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 && options.feePaidBy) {
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 && options.changeAddress) {
772
+ let changeAddress: string;
773
+ if (options?.changeAddress) {
991
774
  changeAddress = options.changeAddress;
992
775
  } else {
993
- changeAddress = this.cashaddr;
776
+ changeAddress = this.getChangeAddress();
994
777
  }
995
778
 
996
779
  let checkTokenQuantities: boolean = true;
997
- if (options && options.checkTokenQuantities === false) {
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: UtxoI[];
785
+ let utxos: Utxo[] = await this.getUtxos();
1003
786
  if (options && options.utxoIds) {
1004
787
  utxos = await checkUtxos(
1005
- options.utxoIds.map((utxoId: UtxoI | string) =>
788
+ options.utxoIds.map((utxoId: Utxo | string) =>
1006
789
  typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId
1007
790
  ),
1008
- this as any
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: UtxoI[],
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: UtxoI[] = [];
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(changeAddress) || this.tokenaddr,
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
- privateKey: privateKey ?? hexToBin(placeholderPrivateKey),
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
- BigInt(spendAmount) + BigInt(Math.ceil(feeEstimate)),
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
- privateKey: privateKey ?? hexToBin(placeholderPrivateKey),
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 ?? hexToBin(placeholderPrivateKey),
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
- return await this.provider.getHistory(this.cashaddr, fromHeight, toHeight);
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: UtxoI[];
1382
- if (options && options.utxoIds) {
1113
+ let utxos: Utxo[] = await this.getUtxos();
1114
+ if (options?.utxoIds) {
1383
1115
  utxos = await checkUtxos(
1384
- options.utxoIds.map((utxoId: UtxoI | string) =>
1116
+ options.utxoIds.map((utxoId: UtxoId | string) =>
1385
1117
  typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId
1386
1118
  ),
1387
- this as any
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.tokenaddr,
1131
+ cashaddr: genesisRequest.cashaddr || this.getTokenDepositAddress(),
1402
1132
  amount: genesisRequest.amount,
1403
- value: genesisRequest.value || 1000,
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.getAddressUtxos(this.cashaddr);
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: this.tokenaddr,
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.tokenaddr,
1476
- amount: 0,
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.getAddressUtxos(this.cashaddr);
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: UtxoI[] = [];
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: burnRequest.cashaddr || this.tokenaddr,
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: burnRequest.cashaddr || this.tokenaddr,
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, 0),
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 {UtxoI[]} token utxos
1348
+ * @returns {Utxo[]} token utxos
1617
1349
  */
1618
- public async getTokenUtxos(tokenId?: string): Promise<UtxoI[]> {
1619
- const utxos = await this.getAddressUtxos(this.cashaddr);
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
- * Class to manage a mainnet watch wallet.
1694
- */
1695
- export class WatchWallet extends BaseWallet {
1696
- static networkPrefix = CashAddressNetworkPrefix.mainnet;
1697
- static walletType = WalletTypeEnum.Watch;
1698
- constructor() {
1699
- super(NetworkType.Mainnet);
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
- * Class to manage a testnet watch wallet.
1705
- */
1706
- export class TestNetWatchWallet extends BaseWallet {
1707
- static networkPrefix = CashAddressNetworkPrefix.testnet;
1708
- static walletType = WalletTypeEnum.Watch;
1709
- constructor() {
1710
- super(NetworkType.Testnet);
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(dbName: string): StorageProvider | undefined {
1502
+ export function getStorageProvider(
1503
+ dbName: string
1504
+ ): StorageProvider | undefined {
1778
1505
  if (!BaseWallet.StorageProvider) {
1779
1506
  return undefined;
1780
1507
  }