Skip to content

Commit 9206f37

Browse files
committed
create addKeyByAlgorithm function
1 parent 3083ebf commit 9206f37

File tree

1 file changed

+75
-28
lines changed
  • packages/bitcore-wallet-client/src/lib

1 file changed

+75
-28
lines changed

packages/bitcore-wallet-client/src/lib/key.ts

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -126,33 +126,7 @@ export class Key {
126126
break;
127127
case 'extendedPrivateKey':
128128
$.checkArgument(x, 'Need to provide opts.seedData');
129-
130-
let xpriv;
131-
try {
132-
xpriv = new Bitcore.HDPrivateKey(x);
133-
} catch (e) {
134-
throw new Error('Invalid argument');
135-
}
136-
for (const algo of SUPPORTED_ALGOS) {
137-
const params = { algo }
138-
this.#setFingerprint({ value: xpriv.fingerPrint.toString('hex'), ...params });
139-
if (opts.password) {
140-
this.#setPrivKeyEncrypted({
141-
value: sjcl.encrypt(
142-
opts.password,
143-
xpriv.toString(),
144-
opts
145-
),
146-
...params
147-
});
148-
const xPrivKeyEncrypted = this.#getPrivKeyEncrypted(params);
149-
if (!xPrivKeyEncrypted) throw new Error('Could not encrypt');
150-
} else {
151-
this.#setPrivKey({ value: xpriv.toString(), ...params });
152-
}
153-
}
154-
this.#mnemonic = null;
155-
this.#mnemonicHasPassphrase = null;
129+
this.setFromExtendedPrivateKey(x, opts);
156130
break;
157131
case 'object':
158132
$.shouldBeObject(x, 'Need to provide an object at opts.seedData');
@@ -240,7 +214,8 @@ export class Key {
240214
m,
241215
opts: { passphrase?: string; password?: string; sjclOpts?: any, algo?: string }
242216
) {
243-
for (const algo of SUPPORTED_ALGOS) {
217+
const algos = opts.algo ? [opts.algo] : SUPPORTED_ALGOS;
218+
for (const algo of algos) {
244219
const xpriv = m.toHDPrivateKey(opts.passphrase, NETWORK, ALGO_TO_KEY_TYPE[algo]);
245220
this.#setFingerprint({ value: xpriv.fingerPrint.toString('hex'), algo });
246221

@@ -267,6 +242,78 @@ export class Key {
267242
}
268243
}
269244

245+
private setFromExtendedPrivateKey (extendedPrivateKey, opts: { password?: string; algo?: string }) {
246+
let xpriv;
247+
if (this.#mnemonic || this.#mnemonicEncrypted) {
248+
throw new Error('Set key from existing mnemonic')
249+
}
250+
try {
251+
xpriv = new Bitcore.HDPrivateKey(extendedPrivateKey);
252+
} catch (e) {
253+
throw new Error('Invalid argument');
254+
}
255+
const algos = opts.algo ? [opts.algo] : SUPPORTED_ALGOS;
256+
for (const algo of algos) {
257+
const params = { algo }
258+
this.#setFingerprint({ value: xpriv.fingerPrint.toString('hex'), ...params });
259+
if (opts.password) {
260+
this.#setPrivKeyEncrypted({
261+
value: sjcl.encrypt(
262+
opts.password,
263+
xpriv.toString(),
264+
opts
265+
),
266+
...params
267+
});
268+
const xPrivKeyEncrypted = this.#getPrivKeyEncrypted(params);
269+
if (!xPrivKeyEncrypted) throw new Error('Could not encrypt');
270+
} else {
271+
this.#setPrivKey({ value: xpriv.toString(), ...params });
272+
}
273+
}
274+
this.#mnemonic = null;
275+
this.#mnemonicHasPassphrase = null;
276+
}
277+
278+
// Adds an additonal supported key to the object
279+
// By default it creates the new key based on the existing bitcoin key (ECDSA)
280+
addKeyByAlgorithm(algo, opts: { passphrase?: string; password?: string; sjclOpts?: any, algo?: string, existingAlgo?: string }) {
281+
const existingAlgo = opts.existingAlgo || 'ECDSA';
282+
if (this.#mnemonic) {
283+
if (this.#mnemonicHasPassphrase) {
284+
if (!opts.passphrase) {
285+
throw new Error('Missing Passphrase')
286+
}
287+
this.setFromMnemonic(this.#mnemonic, { passphrase: opts.passphrase, algo })
288+
} else {
289+
this.setFromMnemonic(this.#mnemonic, { algo });
290+
}
291+
} else if (this.#mnemonicEncrypted) {
292+
if (!opts.password) {
293+
throw new Error('Missing Password')
294+
}
295+
if (this.#mnemonicHasPassphrase) {
296+
if (!opts.passphrase) {
297+
throw new Error('Missing Passphrase')
298+
}
299+
this.setFromMnemonic(this.#mnemonic, { passphrase: opts.passphrase, algo, password: opts.password })
300+
} else {
301+
this.setFromMnemonic(this.#mnemonic, { algo, password: opts.password });
302+
}
303+
} else if (this.#getPrivKeyEncrypted({ algo: existingAlgo })) {
304+
if (!opts.password) {
305+
throw new Error('Missing Password')
306+
}
307+
const xPriv = sjcl.decrypt(opts.password, this.#getPrivKeyEncrypted({ algo: existingAlgo }));
308+
this.setFromExtendedPrivateKey(xPriv, { algo, password: opts.password });
309+
} else if (this.#getPrivKey({ algo: existingAlgo })){
310+
const xPriv = this.#getPrivKey({ algo: existingAlgo });
311+
this.setFromExtendedPrivateKey(xPriv, { algo })
312+
} else {
313+
throw new Error(`Missing Priv Key ${ existingAlgo }`);
314+
}
315+
}
316+
270317
toObj() {
271318
const ret = {
272319
xPrivKey: this.#xPrivKey,

0 commit comments

Comments
 (0)