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
package/src/wallet/Wif.ts CHANGED
@@ -1,28 +1,24 @@
1
1
  //#region Imports
2
2
  import {
3
- deriveSeedFromBip39Mnemonic,
4
- encodeHdPublicKey,
5
- generateBip39Mnemonic,
6
- HdKeyNetwork,
7
- hexToBin,
8
- secp256k1,
9
- } from "@bitauth/libauth";
10
-
11
- import {
3
+ assertSuccess,
12
4
  binToHex,
13
5
  CashAddressNetworkPrefix,
14
6
  decodePrivateKeyWif,
15
7
  deriveHdPath,
16
8
  deriveHdPrivateNodeFromSeed,
17
9
  deriveHdPublicNode,
10
+ deriveSeedFromBip39Mnemonic,
11
+ encodeHdPublicKey,
18
12
  encodePrivateKeyWif,
13
+ generateBip39Mnemonic,
19
14
  generatePrivateKey,
15
+ HdKeyNetwork,
16
+ hexToBin,
17
+ secp256k1,
20
18
  } from "@bitauth/libauth";
21
19
 
22
20
  import { NetworkType } from "../enum.js";
23
21
 
24
- import { PrivateKeyI } from "../interface.js";
25
-
26
22
  import { WalletTypeEnum } from "./enum.js";
27
23
  import { MnemonicI, SendRequestOptionsI, WalletInfoI } from "./interface.js";
28
24
 
@@ -39,41 +35,195 @@ import {
39
35
  import { signUnsignedTransaction } from "../transaction/Wif.js";
40
36
 
41
37
  import { DERIVATION_PATHS } from "../constant.js";
42
- import { SignedMessage, SignedMessageI } from "../message/index.js";
38
+ import {
39
+ SignedMessage,
40
+ SignedMessageI,
41
+ SignedMessageResponseI,
42
+ } from "../message/index.js";
43
43
  import ElectrumNetworkProvider from "../network/ElectrumNetworkProvider.js";
44
44
  import { checkForEmptySeed } from "../util/checkForEmptySeed.js";
45
45
  import { checkWifNetwork } from "../util/checkWifNetwork.js";
46
- import { deriveCashaddr, deriveTokenaddr } from "../util/deriveCashaddr.js";
47
- import { derivePublicKeyHash } from "../util/derivePublicKeyHash.js";
48
- import { getXPubKey } from "../util/getXPubKey.js";
49
46
  import { generateRandomBytes } from "../util/randomBytes.js";
50
47
 
51
48
  import { Config } from "../config.js";
52
- import {
53
- BalanceResponse,
54
- balanceResponseFromSatoshi,
55
- } from "../util/balanceObjectFromSatoshi.js";
56
- import { BaseWallet } from "./Base.js";
49
+ import { WatchWallet } from "./Watch.js";
57
50
  //#endregion Imports
58
51
 
52
+ export interface WalletOptions {
53
+ name?: string;
54
+ mnemonic?: string;
55
+ derivationPath?: string;
56
+ privateKey?: Uint8Array;
57
+ privateKeyWif?: string;
58
+ publicKey?: Uint8Array;
59
+ publicKeyCompressed?: Uint8Array;
60
+ publicKeyHash?: Uint8Array;
61
+ address?: string;
62
+ }
63
+
59
64
  /**
60
65
  * Class to manage a bitcoin cash wallet.
61
66
  */
62
- export class Wallet extends BaseWallet {
67
+ export class Wallet extends WatchWallet {
63
68
  declare readonly provider: ElectrumNetworkProvider;
64
- declare readonly cashaddr: string;
65
- declare readonly tokenaddr: string;
69
+
66
70
  readonly derivationPath: string = Config.DefaultParentDerivationPath + "/0/0";
67
71
  readonly parentDerivationPath: string = Config.DefaultParentDerivationPath;
68
72
  readonly mnemonic!: string;
69
73
  readonly parentXPubKey!: string;
70
74
  readonly privateKey!: Uint8Array;
71
- readonly publicKeyCompressed!: Uint8Array;
72
75
  readonly privateKeyWif!: string;
73
- readonly publicKey!: Uint8Array;
74
- declare readonly publicKeyHash: Uint8Array;
76
+
75
77
  declare name: string;
76
- static readonly signedMessage: SignedMessageI = new SignedMessage();
78
+
79
+ //#region Constructors and Statics
80
+ constructor(
81
+ name = "",
82
+ network = NetworkType.Mainnet,
83
+ walletType = WalletTypeEnum.Seed
84
+ ) {
85
+ super(name, network);
86
+
87
+ this.name = name;
88
+ // @ts-ignore
89
+ this.walletType = walletType;
90
+ }
91
+
92
+ /// Initialize the wallet given the options mnemonic, privateKey or publicKey variations
93
+ /// If none provided, a new random mnemonic will be generated
94
+ /// If mnemonic or private key provided, the wallet will be able to sign transactions
95
+ /// Otherwise, the wallet will be watch-only
96
+ /// This internal method is called by the various static constructors
97
+ protected async initialize({
98
+ name = "",
99
+ mnemonic = undefined,
100
+ derivationPath = undefined,
101
+ privateKey = undefined,
102
+ privateKeyWif = undefined,
103
+ publicKey = undefined,
104
+ publicKeyCompressed = undefined,
105
+ publicKeyHash = undefined,
106
+ address = undefined,
107
+ }: WalletOptions = {}) {
108
+ // seed wallet
109
+ if (this.walletType === WalletTypeEnum.Seed && !mnemonic) {
110
+ mnemonic = generateBip39Mnemonic();
111
+ }
112
+
113
+ if (mnemonic?.length) {
114
+ mnemonic = mnemonic.trim().toLowerCase();
115
+ if (mnemonic.split(" ").length !== 12) {
116
+ throw Error("Invalid mnemonic");
117
+ }
118
+
119
+ if (derivationPath) {
120
+ // @ts-ignore
121
+ this.derivationPath = derivationPath;
122
+
123
+ // If the derivation path is for the first account child, set the parent derivation path
124
+ const path = derivationPath.split("/");
125
+ if (path.slice(-2).join("/") == "0/0") {
126
+ // @ts-ignore
127
+ this.parentDerivationPath = path.slice(0, -2).join("/");
128
+ }
129
+ } else {
130
+ derivationPath = Config.DefaultParentDerivationPath + "/0/0";
131
+ // @ts-ignore
132
+ this.parentDerivationPath = Config.DefaultParentDerivationPath;
133
+ }
134
+
135
+ // @ts-ignore
136
+ this.mnemonic = mnemonic;
137
+ // @ts-ignore
138
+ this.derivationPath = derivationPath;
139
+
140
+ const seed = deriveSeedFromBip39Mnemonic(this.mnemonic);
141
+ checkForEmptySeed(seed);
142
+
143
+ const rootNode = deriveHdPrivateNodeFromSeed(seed, {
144
+ assumeValidity: true,
145
+ throwErrors: true,
146
+ });
147
+ const parentNode = deriveHdPath(rootNode, this.parentDerivationPath);
148
+
149
+ // @ts-ignore
150
+ this.parentXPubKey = assertSuccess(
151
+ encodeHdPublicKey({
152
+ node: deriveHdPublicNode(parentNode),
153
+ network: this.network === NetworkType.Mainnet ? "mainnet" : "testnet",
154
+ })
155
+ ).hdPublicKey;
156
+
157
+ const childNode = deriveHdPath(rootNode, this.derivationPath);
158
+ privateKey = childNode.privateKey;
159
+ }
160
+
161
+ // privkey wallet
162
+ if (this.walletType === WalletTypeEnum.PrivateKey && !privateKey) {
163
+ // @ts-ignore
164
+ this.privateKey = generatePrivateKey(
165
+ () => generateRandomBytes(32) as Uint8Array
166
+ );
167
+ }
168
+
169
+ if (privateKey?.length) {
170
+ // @ts-ignore
171
+ this.privateKey = privateKey;
172
+
173
+ privateKeyWif = encodePrivateKeyWif(
174
+ privateKey,
175
+ this.network === NetworkType.Regtest
176
+ ? NetworkType.Testnet
177
+ : this.network
178
+ );
179
+ }
180
+
181
+ // wif wallet
182
+ if (this.walletType === WalletTypeEnum.Wif && !privateKeyWif) {
183
+ // @ts-ignore
184
+ this.privateKey = generatePrivateKey(
185
+ () => generateRandomBytes(32) as Uint8Array
186
+ );
187
+
188
+ privateKeyWif = encodePrivateKeyWif(
189
+ this.privateKey,
190
+ this.network === NetworkType.Regtest
191
+ ? NetworkType.Testnet
192
+ : this.network
193
+ );
194
+ }
195
+
196
+ if (privateKeyWif?.length) {
197
+ checkWifNetwork(privateKeyWif, this.network);
198
+
199
+ // @ts-ignore
200
+ this.privateKeyWif = privateKeyWif;
201
+
202
+ if (!this.privateKey) {
203
+ // @ts-ignore
204
+ this.privateKey = assertSuccess(
205
+ decodePrivateKeyWif(privateKeyWif)
206
+ ).privateKey;
207
+ }
208
+
209
+ publicKey = assertSuccess(
210
+ secp256k1.derivePublicKeyUncompressed(this.privateKey)
211
+ );
212
+ publicKeyCompressed = assertSuccess(
213
+ secp256k1.compressPublicKey(publicKey!)
214
+ );
215
+ }
216
+
217
+ // rest cases are for watch wallets
218
+ return super.initialize({
219
+ name,
220
+ publicKey,
221
+ publicKeyCompressed,
222
+ publicKeyHash,
223
+ address,
224
+ });
225
+ }
226
+ //#endregion Constructors and Statics
77
227
 
78
228
  //#region Accessors
79
229
  // Get mnemonic and derivation path for wallet
@@ -114,43 +264,68 @@ export class Wallet extends BaseWallet {
114
264
  };
115
265
  }
116
266
 
117
- // returns the public key hash for an address
118
- public getPublicKey(hex = false): string | Uint8Array {
119
- if (this.publicKey) {
120
- return hex ? binToHex(this.publicKey) : this.publicKey;
121
- } else {
122
- throw Error(
123
- "The public key for this wallet is not known, perhaps the wallet was created to watch the *hash* of a public key? i.e. a cashaddress."
124
- );
267
+ // Get common xpub paths from zerothChild privateKey
268
+ public async deriveHdPaths(hdPaths: string[]): Promise<any[]> {
269
+ if (!this.mnemonic)
270
+ throw Error("refusing to create wallet from empty mnemonic");
271
+ const seed = deriveSeedFromBip39Mnemonic(this.mnemonic);
272
+ checkForEmptySeed(seed);
273
+ const hdNode = deriveHdPrivateNodeFromSeed(seed, {
274
+ assumeValidity: true, // TODO: we should switch to libauth's BIP39 implementation and set this to false
275
+ throwErrors: true,
276
+ });
277
+
278
+ const result: any[] = [];
279
+
280
+ for (const path of hdPaths) {
281
+ if (path === "m") {
282
+ throw Error(
283
+ "Storing or sharing of parent public key may lead to loss of funds. Storing or sharing *root* parent public keys is strongly discouraged, although all parent keys have risk. See: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#implications"
284
+ );
285
+ }
286
+ const childNode = deriveHdPath(hdNode, path);
287
+ if (typeof childNode === "string") {
288
+ throw Error(childNode);
289
+ }
290
+ const node = deriveHdPublicNode(childNode);
291
+ if (typeof node === "string") {
292
+ throw Error(node);
293
+ }
294
+ const xPubKey = encodeHdPublicKey(
295
+ {
296
+ network: this.network as HdKeyNetwork,
297
+ node: node,
298
+ },
299
+ {
300
+ throwErrors: true,
301
+ }
302
+ ).hdPublicKey;
303
+ const key = new XPubKey({
304
+ path: path,
305
+ xPubKey: xPubKey,
306
+ });
307
+
308
+ result.push(await key.ready());
125
309
  }
310
+ return await Promise.all(result).then((result) => {
311
+ return result;
312
+ });
126
313
  }
127
314
 
128
- // returns the public key hash for an address
129
- public getPublicKeyCompressed(hex = false): string | Uint8Array {
130
- if (this.publicKeyCompressed) {
131
- return hex
132
- ? binToHex(this.publicKeyCompressed)
133
- : this.publicKeyCompressed;
315
+ public async getXPubKeys(paths?: string[]) {
316
+ if (this.mnemonic) {
317
+ if (paths) {
318
+ let xPubKeys = await this.deriveHdPaths(paths);
319
+ return [xPubKeys];
320
+ } else {
321
+ return await this.deriveHdPaths(DERIVATION_PATHS);
322
+ }
134
323
  } else {
135
- throw Error(
136
- "The compressed public key for this wallet is not known, perhaps the wallet was created to watch the *hash* of a public key? i.e. a cashaddress."
137
- );
324
+ throw Error("xpubkeys can only be derived from seed type wallets.");
138
325
  }
139
326
  }
140
327
  //#endregion
141
328
 
142
- //#region Constructors and Statics
143
- constructor(
144
- name = "",
145
- network = NetworkType.Mainnet,
146
- walletType = WalletTypeEnum.Seed
147
- ) {
148
- super(network);
149
- this.name = name;
150
- // @ts-ignore
151
- this.walletType = walletType;
152
- }
153
-
154
329
  //#region Statics
155
330
  /**
156
331
  * fromId - create a wallet from encoded walletId string
@@ -197,20 +372,19 @@ export class Wallet extends BaseWallet {
197
372
  /**
198
373
  * fromSeed - create a wallet using the seed phrase and derivation path
199
374
  *
200
- * unless specified the derivation path m/44'/245'/0'/0/0 will be userd
201
- * this derivation path is standard for Electron Cash SLP and other SLP enabled wallets
375
+ * unless specified the derivation path m/44'/0'/0'/0/0 will be used
202
376
  *
203
- * @param seed BIP39 12 word seed phrase
377
+ * @param mnemonic BIP39 12 word seed phrase
204
378
  * @param derivationPath BIP44 HD wallet derivation path to get a single the private key from hierarchy
205
379
  *
206
380
  * @returns instantiated wallet
207
381
  */
208
382
  public static async fromSeed<T extends typeof Wallet>(
209
383
  this: T,
210
- seed: string,
384
+ mnemonic: string,
211
385
  derivationPath?: string
212
386
  ): Promise<InstanceType<T>> {
213
- return new this().fromSeed(seed, derivationPath) as InstanceType<T>;
387
+ return new this().fromSeed(mnemonic, derivationPath) as InstanceType<T>;
214
388
  }
215
389
 
216
390
  /**
@@ -233,59 +407,6 @@ export class Wallet extends BaseWallet {
233
407
  //#endregion Constructors
234
408
 
235
409
  //#region Protected implementations
236
- protected async generate(): Promise<this> {
237
- if (this.walletType === WalletTypeEnum.Wif) {
238
- return await this._generateWif();
239
- } else if (this.walletType === WalletTypeEnum.Watch) {
240
- return this;
241
- } else if (this.walletType === WalletTypeEnum.Hd) {
242
- throw Error("Not implemented");
243
- } else if (this.walletType === WalletTypeEnum.Seed) {
244
- return await this._generateMnemonic();
245
- } else {
246
- console.log(this.walletType);
247
- throw Error(`Could not determine walletType: ${this.walletType}`);
248
- }
249
- }
250
-
251
- private async _generateWif() {
252
- if (!this.privateKey) {
253
- // @ts-ignore
254
- this.privateKey = generatePrivateKey(
255
- () => generateRandomBytes(32) as Uint8Array
256
- );
257
- }
258
- return this.deriveInfo();
259
- }
260
-
261
- private async _generateMnemonic() {
262
- // @ts-ignore
263
- this.mnemonic = generateBip39Mnemonic();
264
- if (this.mnemonic.length == 0)
265
- throw Error("refusing to create wallet from empty mnemonic");
266
- const seed = deriveSeedFromBip39Mnemonic(this.mnemonic);
267
- checkForEmptySeed(seed);
268
- const network = this.isTestnet ? "testnet" : "mainnet";
269
- // @ts-ignore
270
- this.parentXPubKey = getXPubKey(seed, this.parentDerivationPath, network);
271
-
272
- const hdNode = deriveHdPrivateNodeFromSeed(seed, {
273
- assumeValidity: true, // TODO: we should switch to libauth's BIP39 implementation and set this to false
274
- throwErrors: true,
275
- });
276
-
277
- const zerothChild = deriveHdPath(hdNode, this.derivationPath);
278
- if (typeof zerothChild === "string") {
279
- throw Error(zerothChild);
280
- }
281
- // @ts-ignore
282
- this.privateKey = zerothChild.privateKey;
283
-
284
- // @ts-ignore
285
- this.walletType = WalletTypeEnum.Seed;
286
- return await this.deriveInfo();
287
- }
288
-
289
410
  protected fromId = async (walletId: string): Promise<this> => {
290
411
  const [walletType, networkGiven, arg1, arg2]: string[] =
291
412
  walletId.split(":");
@@ -332,116 +453,21 @@ export class Wallet extends BaseWallet {
332
453
  }
333
454
  };
334
455
 
335
- public async getXPubKeys(paths?) {
336
- if (this.mnemonic) {
337
- if (paths) {
338
- let xPubKeys = await this.deriveHdPaths(paths);
339
- return [xPubKeys];
340
- } else {
341
- return await this.deriveHdPaths(DERIVATION_PATHS);
342
- }
343
- } else {
344
- throw Error("xpubkeys can only be derived from seed type wallets.");
345
- }
346
- }
347
456
  // Initialize wallet from a mnemonic phrase
348
457
  protected async fromSeed(
349
458
  mnemonic: string,
350
459
  derivationPath?: string
351
460
  ): Promise<this> {
352
- // @ts-ignore
353
- this.mnemonic = mnemonic.trim().toLowerCase();
354
-
355
- if (this.mnemonic.length == 0)
461
+ if (!mnemonic.length) {
356
462
  throw Error("refusing to create wallet from empty mnemonic");
357
- const seed = deriveSeedFromBip39Mnemonic(this.mnemonic);
358
- checkForEmptySeed(seed);
359
- if (this.mnemonic.split(" ").length !== 12) {
360
- throw Error("Invalid mnemonic");
361
463
  }
362
- const hdNode = deriveHdPrivateNodeFromSeed(seed, {
363
- assumeValidity: true, // TODO: we should switch to libauth's BIP39 implementation and set this to false
364
- throwErrors: true,
365
- });
366
- if (derivationPath) {
367
- // @ts-ignore
368
- this.derivationPath = derivationPath;
369
-
370
- // If the derivation path is for the first account child, set the parent derivation path
371
- const path = derivationPath.split("/");
372
- if (path.slice(-2).join("/") == "0/0") {
373
- // @ts-ignore
374
- this.parentDerivationPath = path.slice(0, -2).join("/");
375
- }
376
- }
377
-
378
- const zerothChild = deriveHdPath(hdNode, this.derivationPath);
379
- if (typeof zerothChild === "string") {
380
- throw Error(zerothChild);
381
- }
382
- // @ts-ignore
383
- this.privateKey = zerothChild.privateKey;
384
-
385
- const network = this.isTestnet ? "testnet" : "mainnet";
386
- // @ts-ignore
387
- this.parentXPubKey = await getXPubKey(
388
- seed,
389
- this.parentDerivationPath,
390
- network
391
- );
392
464
 
393
465
  // @ts-ignore
394
466
  this.walletType = WalletTypeEnum.Seed;
395
- await this.deriveInfo();
396
- return this;
397
- }
398
467
 
399
- // Get common xpub paths from zerothChild privateKey
400
- public async deriveHdPaths(hdPaths: string[]): Promise<any[]> {
401
- if (!this.mnemonic)
402
- throw Error("refusing to create wallet from empty mnemonic");
403
- const seed = deriveSeedFromBip39Mnemonic(this.mnemonic);
404
- checkForEmptySeed(seed);
405
- const hdNode = deriveHdPrivateNodeFromSeed(seed, {
406
- assumeValidity: true, // TODO: we should switch to libauth's BIP39 implementation and set this to false
407
- throwErrors: true,
408
- });
409
-
410
- const result: any[] = [];
411
-
412
- for (const path of hdPaths) {
413
- if (path === "m") {
414
- throw Error(
415
- "Storing or sharing of parent public key may lead to loss of funds. Storing or sharing *root* parent public keys is strongly discouraged, although all parent keys have risk. See: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#implications"
416
- );
417
- }
418
- const childNode = deriveHdPath(hdNode, path);
419
- if (typeof childNode === "string") {
420
- throw Error(childNode);
421
- }
422
- const node = deriveHdPublicNode(childNode);
423
- if (typeof node === "string") {
424
- throw Error(node);
425
- }
426
- const xPubKey = encodeHdPublicKey(
427
- {
428
- network: this.network as HdKeyNetwork,
429
- node: node,
430
- },
431
- {
432
- throwErrors: true,
433
- }
434
- ).hdPublicKey;
435
- const key = new XPubKey({
436
- path: path,
437
- xPubKey: xPubKey,
438
- });
468
+ await this.initialize({ mnemonic, derivationPath });
439
469
 
440
- result.push(await key.ready());
441
- }
442
- return await Promise.all(result).then((result) => {
443
- return result;
444
- });
470
+ return this;
445
471
  }
446
472
 
447
473
  // Initialize wallet from private key in hex or Uint8Array
@@ -452,31 +478,21 @@ export class Wallet extends BaseWallet {
452
478
  privateKey = hexToBin(privateKey);
453
479
  }
454
480
 
455
- // @ts-ignore
456
- this.privateKey = privateKey;
457
481
  // @ts-ignore
458
482
  this.walletType = WalletTypeEnum.PrivateKey;
459
- await this.deriveInfo();
483
+
484
+ await this.initialize({ privateKey });
485
+
460
486
  return this;
461
487
  }
462
488
 
463
489
  // Initialize wallet from Wallet Import Format
464
- protected async fromWIF(secret: string): Promise<this> {
465
- checkWifNetwork(secret, this.network);
466
-
467
- let wifResult = decodePrivateKeyWif(secret);
468
-
469
- if (typeof wifResult === "string") {
470
- throw Error(wifResult as string);
471
- }
472
- let resultData: PrivateKeyI = wifResult as PrivateKeyI;
473
- // @ts-ignore
474
- this.privateKey = resultData.privateKey;
475
- // @ts-ignore
476
- this.privateKeyWif = secret;
490
+ protected async fromWIF(privateKeyWif: string): Promise<this> {
477
491
  // @ts-ignore
478
492
  this.walletType = WalletTypeEnum.Wif;
479
- await this.deriveInfo();
493
+
494
+ await this.initialize({ privateKeyWif });
495
+
480
496
  return this;
481
497
  }
482
498
 
@@ -491,7 +507,7 @@ export class Wallet extends BaseWallet {
491
507
  if (name.length > 0) {
492
508
  return this.named(name, dbName);
493
509
  } else {
494
- return this.generate();
510
+ return this.initialize();
495
511
  }
496
512
  }
497
513
  //#endregion Protected Implementations
@@ -538,24 +554,6 @@ export class Wallet extends BaseWallet {
538
554
  //#endregion Serialization
539
555
 
540
556
  //#region Funds
541
- public async getMaxAmountToSend(
542
- params: {
543
- outputCount?: number;
544
- options?: SendRequestOptionsI;
545
- } = {
546
- outputCount: 1,
547
- options: {},
548
- }
549
- ): Promise<BalanceResponse> {
550
- const { value: result } = await this._getMaxAmountToSend({
551
- options: params.options,
552
- outputCount: params.outputCount,
553
- privateKey: this.privateKey,
554
- });
555
-
556
- return await balanceResponseFromSatoshi(result);
557
- }
558
-
559
557
  /**
560
558
  * sendMax Send all available funds to a destination cash address
561
559
  *
@@ -588,11 +586,17 @@ export class Wallet extends BaseWallet {
588
586
  options?: SendRequestOptionsI,
589
587
  privateKey?: Uint8Array
590
588
  ) {
589
+ privateKey = privateKey ?? this.privateKey;
590
+
591
+ if (!privateKey && options?.buildUnsigned !== true) {
592
+ throw new Error(`Missing private key`);
593
+ }
594
+
591
595
  return super.encodeTransaction(
592
596
  requests,
593
597
  discardChange,
594
598
  options,
595
- this.privateKey
599
+ privateKey
596
600
  );
597
601
  }
598
602
 
@@ -608,42 +612,13 @@ export class Wallet extends BaseWallet {
608
612
  }
609
613
  //#endregion Funds
610
614
 
611
- //#region Private implementation details
612
- private async deriveInfo() {
613
- const publicKey = secp256k1.derivePublicKeyUncompressed(this.privateKey);
614
- if (typeof publicKey === "string") {
615
- throw new Error(publicKey);
616
- }
617
- // @ts-ignore
618
- this.publicKey = publicKey;
619
- const publicKeyCompressed = secp256k1.derivePublicKeyCompressed(
620
- this.privateKey
621
- );
622
- if (typeof publicKeyCompressed === "string") {
623
- throw new Error(publicKeyCompressed);
624
- }
625
- // @ts-ignore
626
- this.publicKeyCompressed = publicKeyCompressed;
627
- const networkType =
628
- this.network === NetworkType.Regtest ? NetworkType.Testnet : this.network;
629
- // @ts-ignore
630
- this.privateKeyWif = encodePrivateKeyWif(this.privateKey, networkType);
631
- checkWifNetwork(this.privateKeyWif, this.network);
632
-
633
- // @ts-ignore
634
- this.cashaddr = deriveCashaddr(this.privateKey, this.networkPrefix);
635
- // @ts-ignore
636
- this.tokenaddr = deriveTokenaddr(this.privateKey, this.networkPrefix);
637
- // @ts-ignore
638
- this.publicKeyHash = derivePublicKeyHash(this.cashaddr);
639
- return this;
640
- }
641
- //#endregion Private implementation details
642
-
643
615
  //#region Signing
644
616
  // Convenience wrapper to sign interface
645
- public async sign(message: string) {
646
- return await Wallet.signedMessage.sign(message, this.privateKey);
617
+ public sign(
618
+ message: string,
619
+ privateKey: Uint8Array | undefined = undefined
620
+ ): SignedMessageResponseI {
621
+ return super.sign(message, privateKey ?? this.privateKey);
647
622
  }
648
623
  }
649
624