mainnet-js 2.7.31 → 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.
Files changed (126) hide show
  1. package/dist/index.html +1 -1
  2. package/dist/{mainnet-2.7.31.js → mainnet-3.0.0-next.0.js} +718 -678
  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 +39 -0
  12. package/dist/module/cache/walletCache.d.ts.map +1 -0
  13. package/dist/module/cache/walletCache.js +141 -0
  14. package/dist/module/cache/walletCache.js.map +1 -0
  15. package/dist/module/history/{electrumTransformer.d.ts → getHistory.d.ts} +3 -3
  16. package/dist/module/history/getHistory.d.ts.map +1 -0
  17. package/dist/module/history/{electrumTransformer.js → getHistory.js} +47 -14
  18. package/dist/module/history/getHistory.js.map +1 -0
  19. package/dist/module/index.d.ts +3 -1
  20. package/dist/module/index.d.ts.map +1 -1
  21. package/dist/module/index.js +3 -1
  22. package/dist/module/index.js.map +1 -1
  23. package/dist/module/interface.d.ts +7 -1
  24. package/dist/module/interface.d.ts.map +1 -1
  25. package/dist/module/interface.js.map +1 -1
  26. package/dist/module/message/interface.d.ts +2 -2
  27. package/dist/module/message/interface.d.ts.map +1 -1
  28. package/dist/module/message/interface.js +0 -3
  29. package/dist/module/message/interface.js.map +1 -1
  30. package/dist/module/message/signed.d.ts +5 -5
  31. package/dist/module/message/signed.d.ts.map +1 -1
  32. package/dist/module/message/signed.js +14 -14
  33. package/dist/module/message/signed.js.map +1 -1
  34. package/dist/module/network/ElectrumNetworkProvider.d.ts +2 -2
  35. package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
  36. package/dist/module/network/ElectrumNetworkProvider.js +2 -1
  37. package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
  38. package/dist/module/network/NetworkProvider.d.ts +2 -2
  39. package/dist/module/network/NetworkProvider.d.ts.map +1 -1
  40. package/dist/module/network/constant.js +4 -4
  41. package/dist/module/network/constant.js.map +1 -1
  42. package/dist/module/transaction/Wif.d.ts +21 -19
  43. package/dist/module/transaction/Wif.d.ts.map +1 -1
  44. package/dist/module/transaction/Wif.js +18 -15
  45. package/dist/module/transaction/Wif.js.map +1 -1
  46. package/dist/module/util/checkUtxos.d.ts +2 -2
  47. package/dist/module/util/checkUtxos.d.ts.map +1 -1
  48. package/dist/module/util/checkUtxos.js +11 -12
  49. package/dist/module/util/checkUtxos.js.map +1 -1
  50. package/dist/module/util/deriveCashaddr.d.ts.map +1 -1
  51. package/dist/module/util/deriveCashaddr.js +6 -0
  52. package/dist/module/util/deriveCashaddr.js.map +1 -1
  53. package/dist/module/util/deriveNetwork.js +1 -1
  54. package/dist/module/util/deriveNetwork.js.map +1 -1
  55. package/dist/module/util/hd.d.ts +3 -0
  56. package/dist/module/util/hd.d.ts.map +1 -0
  57. package/dist/module/util/hd.js +11 -0
  58. package/dist/module/util/hd.js.map +1 -0
  59. package/dist/module/util/index.d.ts +1 -0
  60. package/dist/module/util/index.d.ts.map +1 -1
  61. package/dist/module/util/index.js +1 -0
  62. package/dist/module/util/index.js.map +1 -1
  63. package/dist/module/util/sumUtxoValue.d.ts +3 -3
  64. package/dist/module/util/sumUtxoValue.d.ts.map +1 -1
  65. package/dist/module/util/sumUtxoValue.js.map +1 -1
  66. package/dist/module/wallet/Base.d.ts +37 -93
  67. package/dist/module/wallet/Base.d.ts.map +1 -1
  68. package/dist/module/wallet/Base.js +83 -250
  69. package/dist/module/wallet/Base.js.map +1 -1
  70. package/dist/module/wallet/HDWallet.d.ts +164 -0
  71. package/dist/module/wallet/HDWallet.d.ts.map +1 -0
  72. package/dist/module/wallet/HDWallet.js +486 -0
  73. package/dist/module/wallet/HDWallet.js.map +1 -0
  74. package/dist/module/wallet/Watch.d.ts +151 -0
  75. package/dist/module/wallet/Watch.d.ts.map +1 -0
  76. package/dist/module/wallet/Watch.js +307 -0
  77. package/dist/module/wallet/Watch.js.map +1 -0
  78. package/dist/module/wallet/Wif.d.ts +23 -29
  79. package/dist/module/wallet/Wif.d.ts.map +1 -1
  80. package/dist/module/wallet/Wif.js +204 -267
  81. package/dist/module/wallet/Wif.js.map +1 -1
  82. package/dist/module/wallet/createWallet.d.ts +7 -1
  83. package/dist/module/wallet/createWallet.d.ts.map +1 -1
  84. package/dist/module/wallet/createWallet.js +26 -17
  85. package/dist/module/wallet/createWallet.js.map +1 -1
  86. package/dist/module/wallet/interface.d.ts +3 -3
  87. package/dist/module/wallet/interface.d.ts.map +1 -1
  88. package/dist/module/wallet/model.d.ts +3 -3
  89. package/dist/module/wallet/model.d.ts.map +1 -1
  90. package/dist/module/wallet/model.js +2 -18
  91. package/dist/module/wallet/model.js.map +1 -1
  92. package/dist/tsconfig.tsbuildinfo +1 -1
  93. package/package.json +1 -1
  94. package/src/cache/MemoryCache.ts +5 -5
  95. package/src/cache/index.ts +1 -0
  96. package/src/cache/walletCache.ts +252 -0
  97. package/src/history/{electrumTransformer.test.ts → getHistory.test.ts} +6 -19
  98. package/src/history/{electrumTransformer.ts → getHistory.ts} +63 -15
  99. package/src/index.ts +3 -1
  100. package/src/interface.ts +8 -1
  101. package/src/message/interface.ts +2 -28
  102. package/src/message/signed.test.ts +56 -48
  103. package/src/message/signed.ts +15 -18
  104. package/src/network/ElectrumNetworkProvider.ts +4 -4
  105. package/src/network/NetworkProvider.ts +2 -2
  106. package/src/network/Rpc.test.ts +1 -1
  107. package/src/network/constant.ts +4 -4
  108. package/src/transaction/Wif.ts +41 -35
  109. package/src/util/checkUtxos.ts +21 -26
  110. package/src/util/deriveCashaddr.ts +8 -0
  111. package/src/util/deriveNetwork.ts +1 -1
  112. package/src/util/derivePublicKeyHash.test.ts +0 -13
  113. package/src/util/hd.ts +16 -0
  114. package/src/util/index.ts +1 -0
  115. package/src/util/sumUtxoValue.ts +5 -5
  116. package/src/wallet/Base.ts +123 -332
  117. package/src/wallet/HDWallet.test.ts +372 -0
  118. package/src/wallet/HDWallet.ts +764 -0
  119. package/src/wallet/Watch.ts +447 -0
  120. package/src/wallet/Wif.ts +258 -283
  121. package/src/wallet/createWallet.ts +28 -18
  122. package/src/wallet/interface.ts +3 -3
  123. package/src/wallet/model.test.ts +2 -2
  124. package/src/wallet/model.ts +6 -23
  125. package/dist/module/history/electrumTransformer.d.ts.map +0 -1
  126. package/dist/module/history/electrumTransformer.js.map +0 -1
@@ -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 { WalletCacheI } from "../cache/walletCache.js";
9
3
  import StorageProvider from "../db/StorageProvider.js";
4
+ import { NetworkType, prefixFromNetworkMap, UnitEnum } 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,6 +16,7 @@ import {
26
16
  getFeeAmount,
27
17
  getFeeAmountSimple,
28
18
  getSuitableUtxos,
19
+ placeholderPrivateKeyBin,
29
20
  } from "../transaction/Wif.js";
30
21
  import {
31
22
  balanceFromSatoshi,
@@ -33,13 +24,10 @@ import {
33
24
  balanceResponseFromSatoshi,
34
25
  } from "../util/balanceObjectFromSatoshi.js";
35
26
  import { checkUtxos } from "../util/checkUtxos.js";
36
- import { derivePrefix } from "../util/derivePublicKeyHash.js";
37
27
  import {
38
28
  amountInSatoshi,
39
29
  asSendRequestObject,
40
- deriveTokenaddr,
41
30
  getRuntimePlatform,
42
- hexToBin,
43
31
  sumTokenAmounts,
44
32
  sumUtxoValue,
45
33
  toTokenaddr,
@@ -68,10 +56,12 @@ import {
68
56
  TokenSendRequest,
69
57
  } from "./model.js";
70
58
  import { Util } from "./Util.js";
71
- import { Wallet } from "./Wif.js";
59
+ import { SignedMessage } from "../message/signed.js";
72
60
 
73
- const placeholderPrivateKey =
74
- "0000000000000000000000000000000000000000000000000000000000000001";
61
+ export const placeholderCashAddr =
62
+ "bitcoincash:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqfnhks603";
63
+ export const placeholderTokenAddr =
64
+ "bitcoincash:zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqweyg7usz";
75
65
 
76
66
  /**
77
67
  * A class to hold features used by all wallets
@@ -80,13 +70,14 @@ const placeholderPrivateKey =
80
70
  export class BaseWallet implements WalletI {
81
71
  public static StorageProvider?: typeof StorageProvider;
82
72
 
73
+ readonly walletCache?: WalletCacheI;
83
74
  readonly provider: ElectrumNetworkProvider;
84
75
  readonly network: NetworkType;
85
76
  readonly walletType: WalletTypeEnum;
86
77
  _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;
78
+ // readonly publicKeyHash!: Uint8Array;
79
+ // readonly cashaddr!: string;
80
+ // readonly tokenaddr!: string;
90
81
  readonly isTestnet: boolean;
91
82
  name: string = "";
92
83
  _util?: Util;
@@ -111,16 +102,7 @@ export class BaseWallet implements WalletI {
111
102
 
112
103
  // Return wallet info
113
104
  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
- };
105
+ throw Error("getInfo not implemented in BaseWallet");
124
106
  }
125
107
 
126
108
  public slpSemiAware(value: boolean = true): this {
@@ -146,7 +128,22 @@ export class BaseWallet implements WalletI {
146
128
  * @returns The deposit address as a string
147
129
  */
148
130
  public getDepositAddress(): string {
149
- return this.cashaddr;
131
+ // return this.cashaddr;
132
+ throw Error("getDepositAddress not implemented in BaseWallet");
133
+ }
134
+
135
+ /**
136
+ * getChangeAddress - get a wallet change address
137
+ *
138
+ * a high-level function,
139
+ *
140
+ * @see {@link https://rest-unstable.mainnet.cash/api-docs/#/wallet/changeAddress|/wallet/change_address} for REST endpoint
141
+ *
142
+ * @returns The change address as a string
143
+ */
144
+ public getChangeAddress(): string {
145
+ // return this.cashaddr;
146
+ throw Error("getChangeAddress not implemented in BaseWallet");
150
147
  }
151
148
 
152
149
  /**
@@ -155,7 +152,18 @@ export class BaseWallet implements WalletI {
155
152
  * @returns The cashtoken aware deposit address as a string
156
153
  */
157
154
  public getTokenDepositAddress(): string {
158
- return this.tokenaddr;
155
+ // return this.tokenaddr;
156
+ throw Error("getTokenDepositAddress not implemented in BaseWallet");
157
+ }
158
+
159
+ /**
160
+ * getTokenDepositAddress - get a cashtoken aware wallet deposit address
161
+ *
162
+ * @returns The cashtoken aware deposit address as a string
163
+ */
164
+ public getTokenChangeAddress(): string {
165
+ // return this.tokenaddr;
166
+ throw Error("getTokenDepositAddress not implemented in BaseWallet");
159
167
  }
160
168
  //#endregion Accessors
161
169
 
@@ -172,23 +180,6 @@ export class BaseWallet implements WalletI {
172
180
  this.provider = this.getNetworkProvider(this.network);
173
181
  this.isTestnet = this.network === NetworkType.Mainnet ? false : true;
174
182
  }
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
183
  //#endregion Constructors
193
184
 
194
185
  /**
@@ -230,7 +221,8 @@ export class BaseWallet implements WalletI {
230
221
  recoveredWallet.name = savedWalletRecord.name;
231
222
  return recoveredWallet;
232
223
  } else {
233
- const wallet = await this.generate();
224
+ const wallet = await this.initialize();
225
+ wallet.name = name;
234
226
  await db.addWallet(wallet.name, wallet.toDbString());
235
227
  await db.close();
236
228
  return wallet;
@@ -314,7 +306,7 @@ export class BaseWallet implements WalletI {
314
306
  }
315
307
  }
316
308
 
317
- protected async generate(): Promise<this> {
309
+ protected async initialize(): Promise<this> {
318
310
  return this;
319
311
  }
320
312
 
@@ -353,55 +345,6 @@ export class BaseWallet implements WalletI {
353
345
  return explorerUrlMap[this.network] + txId;
354
346
  }
355
347
 
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
348
  /**
406
349
  * named - create a named wallet
407
350
  *
@@ -411,7 +354,7 @@ export class BaseWallet implements WalletI {
411
354
  *
412
355
  * @returns instantiated wallet
413
356
  */
414
- public static async named<T extends typeof Wallet>(
357
+ public static async named<T extends typeof BaseWallet>(
415
358
  this: T,
416
359
  name: string,
417
360
  dbName?: string,
@@ -432,7 +375,7 @@ export class BaseWallet implements WalletI {
432
375
  *
433
376
  * @returns instantiated wallet
434
377
  */
435
- public static async replaceNamed<T extends typeof Wallet>(
378
+ public static async replaceNamed<T extends typeof BaseWallet>(
436
379
  this: T,
437
380
  name: string,
438
381
  walletId: string,
@@ -457,87 +400,16 @@ export class BaseWallet implements WalletI {
457
400
  }
458
401
 
459
402
  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);
403
+ throw Error("fromId not implemented in BaseWallet");
478
404
  }
479
405
 
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
406
  //#region Funds
532
407
  /**
533
408
  * utxos Get unspent outputs for the wallet
534
409
  *
535
410
  */
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);
411
+ public async getUtxos(): Promise<Utxo[]> {
412
+ throw Error("getUtxos not implemented in BaseWallet");
541
413
  }
542
414
 
543
415
  // gets wallet balance in sats, bch and currency
@@ -562,7 +434,7 @@ export class BaseWallet implements WalletI {
562
434
 
563
435
  // Gets balance by summing value in all utxos in stats
564
436
  public async getBalanceFromUtxos(): Promise<number> {
565
- const utxos = (await this.getAddressUtxos(this.cashaddr)).filter(
437
+ const utxos = (await this.getUtxos()).filter(
566
438
  (val) => val.token === undefined
567
439
  );
568
440
  return sumUtxoValue(utxos);
@@ -582,19 +454,8 @@ export class BaseWallet implements WalletI {
582
454
  return this.getBalanceFromUtxos();
583
455
  }
584
456
 
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
- }
457
+ public async getAddressUtxos(address?: string): Promise<Utxo[]> {
458
+ throw Error("getAddressUtxos not implemented in BaseWallet");
598
459
  }
599
460
 
600
461
  // watching for any transaction hash of this wallet
@@ -740,14 +601,7 @@ export class BaseWallet implements WalletI {
740
601
  outputCount: 1,
741
602
  options: {},
742
603
  }
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
-
604
+ ): Promise<{ value: number; utxos: Utxo[] }> {
751
605
  if (params.options && params.options.slpSemiAware) {
752
606
  this._slpSemiAware = true;
753
607
  }
@@ -760,18 +614,16 @@ export class BaseWallet implements WalletI {
760
614
  }
761
615
 
762
616
  // get inputs
763
- let utxos: UtxoI[];
617
+ let utxos: Utxo[];
764
618
  if (params.options && params.options.utxoIds) {
765
619
  utxos = await checkUtxos(
766
- params.options.utxoIds.map((utxoId: UtxoI | string) =>
620
+ params.options.utxoIds.map((utxoId: Utxo | string) =>
767
621
  typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId
768
622
  ),
769
623
  this as any
770
624
  );
771
625
  } else {
772
- utxos = (await this.getAddressUtxos(this.cashaddr)).filter(
773
- (utxo) => !utxo.token
774
- );
626
+ utxos = (await this.getUtxos()).filter((utxo) => !utxo.token);
775
627
  }
776
628
 
777
629
  // Get current height to assure recently mined coins are not spent.
@@ -779,7 +631,7 @@ export class BaseWallet implements WalletI {
779
631
 
780
632
  // simulate outputs using the sender's address
781
633
  const sendRequest = new SendRequest({
782
- cashaddr: this.cashaddr,
634
+ cashaddr: placeholderCashAddr,
783
635
  value: 100,
784
636
  unit: "sat",
785
637
  });
@@ -798,8 +650,7 @@ export class BaseWallet implements WalletI {
798
650
  const fee = await getFeeAmountSimple({
799
651
  utxos: fundingUtxos,
800
652
  sendRequests: sendRequests,
801
- privateKey: params.privateKey ?? hexToBin(placeholderPrivateKey),
802
- sourceAddress: this.cashaddr,
653
+ sourceAddress: placeholderCashAddr,
803
654
  relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
804
655
  feePaidBy: feePaidBy,
805
656
  });
@@ -971,44 +822,38 @@ export class BaseWallet implements WalletI {
971
822
  ) {
972
823
  let sendRequests = asSendRequestObject(requests);
973
824
 
974
- if (!privateKey && options?.buildUnsigned !== true) {
975
- throw new Error(`Missing private key`);
976
- }
977
-
978
825
  if (options && options.slpSemiAware) {
979
826
  this._slpSemiAware = true;
980
827
  }
981
828
 
982
- let feePaidBy;
983
- if (options && options.feePaidBy) {
829
+ let feePaidBy: FeePaidByEnum;
830
+ if (options?.feePaidBy) {
984
831
  feePaidBy = options.feePaidBy;
985
832
  } else {
986
833
  feePaidBy = FeePaidByEnum.change;
987
834
  }
988
835
 
989
- let changeAddress;
990
- if (options && options.changeAddress) {
836
+ let changeAddress: string;
837
+ if (options?.changeAddress) {
991
838
  changeAddress = options.changeAddress;
992
839
  } else {
993
- changeAddress = this.cashaddr;
840
+ changeAddress = this.getChangeAddress();
994
841
  }
995
842
 
996
843
  let checkTokenQuantities: boolean = true;
997
- if (options && options.checkTokenQuantities === false) {
844
+ if (options?.checkTokenQuantities === false) {
998
845
  checkTokenQuantities = false;
999
846
  }
1000
847
 
1001
848
  // get inputs from options or query all inputs
1002
- let utxos: UtxoI[];
849
+ let utxos: Utxo[] = await this.getUtxos();
1003
850
  if (options && options.utxoIds) {
1004
851
  utxos = await checkUtxos(
1005
- options.utxoIds.map((utxoId: UtxoI | string) =>
852
+ options.utxoIds.map((utxoId: Utxo | string) =>
1006
853
  typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId
1007
854
  ),
1008
- this as any
855
+ utxos
1009
856
  );
1010
- } else {
1011
- utxos = await this.getAddressUtxos(this.cashaddr);
1012
857
  }
1013
858
 
1014
859
  // filter out token utxos if there are no token requests
@@ -1020,7 +865,7 @@ export class BaseWallet implements WalletI {
1020
865
  }
1021
866
 
1022
867
  const addTokenChangeOutputs = (
1023
- inputs: UtxoI[],
868
+ inputs: Utxo[],
1024
869
  outputs: SendRequestType[]
1025
870
  ) => {
1026
871
  // Allow for implicit token burn if the total amount sent is less than user had
@@ -1058,7 +903,7 @@ export class BaseWallet implements WalletI {
1058
903
  if (diff >= 0) {
1059
904
  let available = 0n;
1060
905
  let change = 0n;
1061
- const ensureUtxos: UtxoI[] = [];
906
+ const ensureUtxos: Utxo[] = [];
1062
907
  for (const token of tokenInputs.filter((val) => val.token?.amount)) {
1063
908
  ensureUtxos.push(token);
1064
909
  available += token.token!.amount;
@@ -1084,7 +929,7 @@ export class BaseWallet implements WalletI {
1084
929
  if (change > 0) {
1085
930
  outputs.push(
1086
931
  new TokenSendRequest({
1087
- cashaddr: toTokenaddr(changeAddress) || this.tokenaddr,
932
+ cashaddr: toTokenaddr(this.getChangeAddress()),
1088
933
  amount: change,
1089
934
  tokenId: tokenId,
1090
935
  commitment: tokenOutputs[0].commitment,
@@ -1112,8 +957,7 @@ export class BaseWallet implements WalletI {
1112
957
  const feeEstimate = await getFeeAmountSimple({
1113
958
  utxos: utxos,
1114
959
  sendRequests: sendRequests,
1115
- privateKey: privateKey ?? hexToBin(placeholderPrivateKey),
1116
- sourceAddress: this.cashaddr,
960
+ sourceAddress: this.getDepositAddress(),
1117
961
  relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
1118
962
  feePaidBy: feePaidBy,
1119
963
  });
@@ -1135,22 +979,22 @@ export class BaseWallet implements WalletI {
1135
979
  const fee = await getFeeAmount({
1136
980
  utxos: fundingUtxos,
1137
981
  sendRequests: sendRequests,
1138
- privateKey: privateKey ?? hexToBin(placeholderPrivateKey),
1139
- sourceAddress: this.cashaddr,
982
+ sourceAddress: this.getDepositAddress(),
1140
983
  relayFeePerByteInSatoshi: relayFeePerByteInSatoshi,
1141
984
  feePaidBy: feePaidBy,
985
+ walletCache: this.walletCache,
1142
986
  });
1143
987
  const { encodedTransaction, sourceOutputs } = await buildEncodedTransaction(
1144
988
  {
1145
989
  inputs: fundingUtxos,
1146
990
  outputs: sendRequests,
1147
- signingKey: privateKey ?? hexToBin(placeholderPrivateKey),
1148
- sourceAddress: this.cashaddr,
991
+ signingKey: privateKey ?? placeholderPrivateKeyBin,
1149
992
  fee,
1150
993
  discardChange,
1151
994
  feePaidBy,
1152
995
  changeAddress,
1153
996
  buildUnsigned: options?.buildUnsigned === true,
997
+ walletCache: this.walletCache,
1154
998
  }
1155
999
  );
1156
1000
 
@@ -1186,45 +1030,7 @@ export class BaseWallet implements WalletI {
1186
1030
  fromHeight: number = 0,
1187
1031
  toHeight: number = -1
1188
1032
  ): 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
- });
1033
+ throw Error("getRawHistory not implemented in BaseWallet");
1228
1034
  }
1229
1035
 
1230
1036
  // gets last transaction of this wallet
@@ -1347,16 +1153,6 @@ export class BaseWallet implements WalletI {
1347
1153
 
1348
1154
  //#endregion Funds
1349
1155
 
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
1156
  //#region Cashtokens
1361
1157
  /**
1362
1158
  * Create new cashtoken, both funglible and/or non-fungible (NFT)
@@ -1378,16 +1174,14 @@ export class BaseWallet implements WalletI {
1378
1174
  sendRequests = [sendRequests];
1379
1175
  }
1380
1176
 
1381
- let utxos: UtxoI[];
1382
- if (options && options.utxoIds) {
1177
+ let utxos: Utxo[] = await this.getUtxos();
1178
+ if (options?.utxoIds) {
1383
1179
  utxos = await checkUtxos(
1384
- options.utxoIds.map((utxoId: UtxoI | string) =>
1180
+ options.utxoIds.map((utxoId: UtxoId | string) =>
1385
1181
  typeof utxoId === "string" ? fromUtxoId(utxoId) : utxoId
1386
1182
  ),
1387
- this as any
1183
+ utxos
1388
1184
  );
1389
- } else {
1390
- utxos = await this.getAddressUtxos(this.cashaddr);
1391
1185
  }
1392
1186
 
1393
1187
  const genesisInputs = utxos.filter((val) => val.vout === 0 && !val.token);
@@ -1398,7 +1192,7 @@ export class BaseWallet implements WalletI {
1398
1192
  }
1399
1193
 
1400
1194
  const genesisSendRequest = new TokenSendRequest({
1401
- cashaddr: genesisRequest.cashaddr || this.tokenaddr,
1195
+ cashaddr: genesisRequest.cashaddr || this.getTokenDepositAddress(),
1402
1196
  amount: genesisRequest.amount,
1403
1197
  value: genesisRequest.value || 1000,
1404
1198
  capability: genesisRequest.capability,
@@ -1442,7 +1236,7 @@ export class BaseWallet implements WalletI {
1442
1236
  mintRequests = [mintRequests];
1443
1237
  }
1444
1238
 
1445
- const utxos = await this.getAddressUtxos(this.cashaddr);
1239
+ const utxos = await this.getUtxos();
1446
1240
  const nftUtxos = utxos.filter(
1447
1241
  (val) =>
1448
1242
  val.token?.tokenId === tokenId &&
@@ -1459,7 +1253,7 @@ export class BaseWallet implements WalletI {
1459
1253
  : nftUtxos[0].token!.amount;
1460
1254
  const safeNewAmount = newAmount < 0n ? 0n : newAmount;
1461
1255
  const mintingInput = new TokenSendRequest({
1462
- cashaddr: this.tokenaddr,
1256
+ cashaddr: toTokenaddr(nftUtxos[0].address),
1463
1257
  tokenId: tokenId,
1464
1258
  capability: nftUtxos[0].token!.capability,
1465
1259
  commitment: nftUtxos[0].token!.commitment,
@@ -1472,7 +1266,7 @@ export class BaseWallet implements WalletI {
1472
1266
  ...mintRequests.map(
1473
1267
  (val) =>
1474
1268
  new TokenSendRequest({
1475
- cashaddr: val.cashaddr || this.tokenaddr,
1269
+ cashaddr: val.cashaddr || this.getTokenDepositAddress(),
1476
1270
  amount: 0,
1477
1271
  tokenId: tokenId,
1478
1272
  value: val.value,
@@ -1516,7 +1310,7 @@ export class BaseWallet implements WalletI {
1516
1310
  throw Error(`Invalid tokenId supplied: ${burnRequest.tokenId}`);
1517
1311
  }
1518
1312
 
1519
- const utxos = await this.getAddressUtxos(this.cashaddr);
1313
+ const utxos = await this.getUtxos();
1520
1314
  const tokenUtxos = utxos.filter(
1521
1315
  (val) =>
1522
1316
  val.token?.tokenId === burnRequest.tokenId &&
@@ -1537,7 +1331,7 @@ export class BaseWallet implements WalletI {
1537
1331
  fungibleBurnAmount = BigInt(fungibleBurnAmount);
1538
1332
  const hasNFT = burnRequest.capability || burnRequest.commitment;
1539
1333
 
1540
- let utxoIds: UtxoI[] = [];
1334
+ let utxoIds: Utxo[] = [];
1541
1335
  let changeSendRequests: TokenSendRequest[];
1542
1336
  if (hasNFT) {
1543
1337
  // does not have FT tokens, let us destroy the token completely
@@ -1560,7 +1354,8 @@ export class BaseWallet implements WalletI {
1560
1354
  const safeNewAmount = newAmount < 0n ? 0n : newAmount;
1561
1355
  changeSendRequests = [
1562
1356
  new TokenSendRequest({
1563
- cashaddr: burnRequest.cashaddr || this.tokenaddr,
1357
+ cashaddr:
1358
+ burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
1564
1359
  tokenId: burnRequest.tokenId,
1565
1360
  capability: burnRequest.capability,
1566
1361
  commitment: burnRequest.commitment,
@@ -1590,7 +1385,8 @@ export class BaseWallet implements WalletI {
1590
1385
  const safeNewAmount = newAmount < 0n ? 0n : newAmount;
1591
1386
  changeSendRequests = [
1592
1387
  new TokenSendRequest({
1593
- cashaddr: burnRequest.cashaddr || this.tokenaddr,
1388
+ cashaddr:
1389
+ burnRequest.cashaddr || toTokenaddr(this.getChangeAddress()),
1594
1390
  tokenId: burnRequest.tokenId,
1595
1391
  amount: safeNewAmount,
1596
1392
  value: tokenUtxos.reduce((a, c) => a + c.satoshis, 0),
@@ -1613,10 +1409,10 @@ export class BaseWallet implements WalletI {
1613
1409
  * getTokenUtxos Get unspent token outputs for the wallet
1614
1410
  * will return utxos only for the specified token if `tokenId` provided
1615
1411
  * @param {string?} tokenId tokenId (category) to filter utxos by, if not set will return utxos from all tokens
1616
- * @returns {UtxoI[]} token utxos
1412
+ * @returns {Utxo[]} token utxos
1617
1413
  */
1618
- public async getTokenUtxos(tokenId?: string): Promise<UtxoI[]> {
1619
- const utxos = await this.getAddressUtxos(this.cashaddr);
1414
+ public async getTokenUtxos(tokenId?: string): Promise<Utxo[]> {
1415
+ const utxos = await this.getUtxos();
1620
1416
  return utxos.filter((val) =>
1621
1417
  tokenId ? val.token?.tokenId === tokenId : val.token
1622
1418
  );
@@ -1687,38 +1483,31 @@ export class BaseWallet implements WalletI {
1687
1483
  return result;
1688
1484
  }
1689
1485
  //#endregion Cashtokens
1690
- }
1691
1486
 
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);
1487
+ public sign(
1488
+ message: string,
1489
+ privateKey: Uint8Array | undefined = undefined
1490
+ ): SignedMessageResponseI {
1491
+ if (!privateKey) {
1492
+ throw new Error("Signing private key not provided");
1493
+ }
1494
+ return new SignedMessage().sign(message, privateKey);
1700
1495
  }
1701
- }
1702
1496
 
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
- }
1497
+ // Convenience wrapper to verify interface
1498
+ public verify(
1499
+ message: string,
1500
+ sig: string,
1501
+ address?: string,
1502
+ publicKey?: Uint8Array
1503
+ ): VerifyMessageResponseI {
1504
+ if (!address && !publicKey) {
1505
+ throw new Error(
1506
+ "Either address or publicKey must be provided for verification"
1507
+ );
1508
+ }
1713
1509
 
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);
1510
+ return new SignedMessage().verify(message, sig, address, publicKey);
1722
1511
  }
1723
1512
  }
1724
1513
 
@@ -1727,7 +1516,7 @@ export class RegTestWatchWallet extends BaseWallet {
1727
1516
  * mainnet wallets on public servers if ALLOW_MAINNET_USER_WALLETS is set to false
1728
1517
  * @param {BaseWallet} wallet a wallet
1729
1518
  */
1730
- const _checkContextSafety = function (wallet: BaseWallet) {
1519
+ export const _checkContextSafety = function (wallet: BaseWallet) {
1731
1520
  if (getRuntimePlatform() === "node") {
1732
1521
  if (process.env.ALLOW_MAINNET_USER_WALLETS === `false`) {
1733
1522
  if (wallet.network === NetworkType.Mainnet) {
@@ -1774,7 +1563,9 @@ export async function getNamedWalletId(
1774
1563
  }
1775
1564
  }
1776
1565
 
1777
- function getStorageProvider(dbName: string): StorageProvider | undefined {
1566
+ export function getStorageProvider(
1567
+ dbName: string
1568
+ ): StorageProvider | undefined {
1778
1569
  if (!BaseWallet.StorageProvider) {
1779
1570
  return undefined;
1780
1571
  }