Skip to content
This repository has been archived by the owner on Jul 7, 2021. It is now read-only.

Commit

Permalink
refactor(profiles): replace fromMnemonicWithEncryption with a `pass…
Browse files Browse the repository at this point in the history
…word` argument for `fromMnemonicWithBIP39` (#1691)
  • Loading branch information
faustbrian committed Jun 3, 2021
1 parent b339569 commit 3533031
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 60 deletions.
Expand Up @@ -20,6 +20,7 @@ export interface IMnemonicOptions {
coin: string;
network: string;
mnemonic: string;
password?: string;
}

/**
Expand Down Expand Up @@ -67,18 +68,6 @@ export interface IAddressWithDerivationPathOptions {
path: string;
}

/**
* Defines the options for an import with a mnemonic and password.
*
* @interface IMnemonicWithEncryptionOptions
*/
export interface IMnemonicWithEncryptionOptions {
coin: string;
network: string;
mnemonic: string;
password: string;
}

/**
* Defines the options for an import with a WIF.
*
Expand Down Expand Up @@ -190,15 +179,6 @@ export interface IWalletFactory {
*/
fromAddressWithDerivationPath(options: IAddressWithDerivationPathOptions): Promise<IReadWriteWallet>;

/**
* Imports a wallet from a mnemonic with a password.
*
* @param {IMnemonicWithEncryptionOptions} options
* @return {Promise<IReadWriteWallet>}
* @memberof IWalletFactory
*/
fromMnemonicWithEncryption(options: IMnemonicWithEncryptionOptions): Promise<IReadWriteWallet>;

/**
* Imports a wallet from a WIF.
*
Expand Down
Expand Up @@ -76,6 +76,24 @@ describe("#fromMnemonicWithBIP39", () => {
}),
).rejects.toThrow("The configured network uses extended public keys with BIP44 for derivation.");
});

it("should create a wallet using BIP39 with encryption", async () => {
const wallet = await subject.fromMnemonicWithBIP39({
coin: "ARK",
network: "ark.devnet",
mnemonic: "this is a top secret passphrase",
password: "password",
});

expect(wallet.address()).toBe("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib");
expect(wallet.publicKey()).toBe("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192");
expect(wallet.data().get(WalletData.Bip38EncryptedKey)).toBeString();

// @ts-ignore
expect(decrypt(wallet.data().get(WalletData.Bip38EncryptedKey)!, "password").privateKey.toString("hex")).toBe(
"d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712",
);
});
});

describe("#fromMnemonicWithBIP44", () => {
Expand Down Expand Up @@ -160,24 +178,6 @@ test("#fromAddressWithDerivationPath", async () => {
expect(wallet.publicKey()).toBe("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192");
});

test("#fromMnemonicWithEncryption", async () => {
const wallet = await subject.fromMnemonicWithEncryption({
coin: "ARK",
network: "ark.devnet",
mnemonic: "this is a top secret passphrase",
password: "password",
});

expect(wallet.address()).toBe("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib");
expect(wallet.publicKey()).toBe("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192");
expect(wallet.data().get(WalletData.Bip38EncryptedKey)).toBeString();

// @ts-ignore
expect(decrypt(wallet.data().get(WalletData.Bip38EncryptedKey)!, "password").privateKey.toString("hex")).toBe(
"d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712",
);
});

test("#fromWIF", async () => {
const wallet = await subject.fromWIF({
coin: "ARK",
Expand Down
Expand Up @@ -10,7 +10,6 @@ import {
IAddressWithDerivationPathOptions,
IGenerateOptions,
IMnemonicOptions,
IMnemonicWithEncryptionOptions,
IPrivateKeyOptions,
IProfile,
IPublicKeyOptions,
Expand Down Expand Up @@ -43,7 +42,7 @@ export class WalletFactory implements IWalletFactory {
}

/** {@inheritDoc IWalletFactory.fromMnemonicWithBIP39} */
public async fromMnemonicWithBIP39({ coin, network, mnemonic }: IMnemonicOptions): Promise<IReadWriteWallet> {
public async fromMnemonicWithBIP39({ coin, network, mnemonic, password }: IMnemonicOptions): Promise<IReadWriteWallet> {
const wallet: IReadWriteWallet = new Wallet(uuidv4(), {}, this.#profile);

wallet.data().set(WalletData.ImportMethod, WalletImportMethod.MnemonicBIP39);
Expand All @@ -60,6 +59,14 @@ export class WalletFactory implements IWalletFactory {

await wallet.mutator().identity(mnemonic);

if (password) {
await this.#encryptWallet(
wallet,
password,
async () => await wallet.coin().identity().wif().fromMnemonic(mnemonic),
);
}

return wallet;
}

Expand Down Expand Up @@ -153,8 +160,6 @@ export class WalletFactory implements IWalletFactory {
address,
path,
}: IAddressWithDerivationPathOptions): Promise<IReadWriteWallet> {
// @TODO: eventually handle the whole process from slip44 path to public key to address

const wallet: IReadWriteWallet = await this.fromAddress({ coin, network, address });
wallet.data().set(WalletData.ImportMethod, WalletImportMethod.AddressWithDerivationPath);

Expand All @@ -163,23 +168,6 @@ export class WalletFactory implements IWalletFactory {
return wallet;
}

/** {@inheritDoc IWalletFactory.fromMnemonicWithEncryption} */
public async fromMnemonicWithEncryption({
coin,
network,
mnemonic,
password,
}: IMnemonicWithEncryptionOptions): Promise<IReadWriteWallet> {
const wallet: IReadWriteWallet = await this.fromMnemonicWithBIP39({ coin, network, mnemonic });
wallet.data().set(WalletData.ImportMethod, WalletImportMethod.MnemonicWithEncryption);

const { compressed, privateKey } = decode((await wallet.coin().identity().wif().fromMnemonic(mnemonic)).wif);

wallet.data().set(WalletData.Bip38EncryptedKey, encrypt(privateKey, compressed, password));

return wallet;
}

/** {@inheritDoc IWalletFactory.fromWIF} */
public async fromWIF({ coin, network, wif }: IWifOptions): Promise<IReadWriteWallet> {
const wallet: IReadWriteWallet = new Wallet(uuidv4(), {}, this.#profile);
Expand Down Expand Up @@ -233,4 +221,10 @@ export class WalletFactory implements IWalletFactory {
/* istanbul ignore next */
return wallet.gate().allows(Coins.FeatureFlag.IdentityAddressMnemonicBip84);
}

async #encryptWallet(wallet: IReadWriteWallet, password: string, derive: Function): Promise<void> {
const { compressed, privateKey } = decode((await derive()).wif);

wallet.data().set(WalletData.Bip38EncryptedKey, encrypt(privateKey, compressed, password));
}
}

0 comments on commit 3533031

Please sign in to comment.