Skip to content

Commit

Permalink
Merge pull request #22 from leapwallet/fix/sign-message
Browse files Browse the repository at this point in the history
update ethWallet
  • Loading branch information
baryon2 authored Mar 15, 2024
2 parents 326818e + 3d58ae1 commit e97c4d8
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@leapwallet/leap-keychain",
"version": "0.2.3-beta.1",
"version": "0.2.3-beta.2",
"description": "A javascript library for crypto key management",
"scripts": {
"test": "jest",
Expand Down
10 changes: 8 additions & 2 deletions src/key/eth-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { bip39Token, getBip39 } from '../crypto/bip39/bip39-token';
import { SignDoc } from 'cosmjs-types/cosmos/tx/v1beta1/tx';
import { TransactionRequest, Provider } from '@ethersproject/abstract-provider';
import Container from 'typedi';
import { pubkeyToAddress } from './wallet';

export class EthWallet {
private constructor(
Expand Down Expand Up @@ -72,13 +73,18 @@ export class EthWallet {
this.walletType === 'mnemonic' ? HDNode.fromSeed(seed).derivePath(path) : new Wallet(this.pvtKey);

const ethAddr = EthereumUtilsAddress.fromString(hdWallet.address).toBuffer();
const bech32Address = bech32.encode(this.options.addressPrefix, bech32.toWords(ethAddr));

const ethWallet = new Wallet(hdWallet.privateKey, this.provider);
const pubkey = fromHex(ethWallet._signingKey().compressedPublicKey.replace('0x', ''));

const bech32Address = this.options.pubKeyBech32Address
? pubkeyToAddress(this.options.addressPrefix, pubkey)
: bech32.encode(this.options.addressPrefix, bech32.toWords(ethAddr));
return {
algo: 'ethsecp256k1',
address: bech32Address,
ethWallet: ethWallet,
pubkey: fromHex(ethWallet._signingKey().compressedPublicKey.replace('0x', '')),
pubkey,
};
});
}
Expand Down
16 changes: 12 additions & 4 deletions src/key/wallet-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,24 @@ import { bip39Token } from '../crypto/bip39/bip39-token';

export function generateWalletFromMnemonic(
mnemonic: string,
hdPath: string,
addressPrefix: string,
ethWallet?: boolean,
{
hdPath,
addressPrefix,
ethWallet,
pubKeyBech32Address,
}: {
hdPath: string;
addressPrefix: string;
ethWallet: boolean;
pubKeyBech32Address?: boolean;
},
) {
const bip39 = Container.get(bip39Token);
bip39.mnemonicToEntropy(mnemonic);
const hdPathParams = hdPath.split('/');
const coinType = hdPathParams[2];
if (coinType?.replace("'", '') === '60' || ethWallet) {
return EthWallet.generateWalletFromMnemonic(mnemonic, { paths: [hdPath], addressPrefix });
return EthWallet.generateWalletFromMnemonic(mnemonic, { paths: [hdPath], addressPrefix, pubKeyBech32Address });
}
return Wallet.generateWallet(mnemonic, { paths: [hdPath], addressPrefix });
}
Expand Down
28 changes: 18 additions & 10 deletions src/keychain/keychain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,17 @@ export class KeyChain {
public static async getSigner<T extends string>(
walletId: string,
password: string,
addressPrefix: string,
coinType: string,
ethWallet?: boolean,
{
addressPrefix,
coinType,
ethWallet,
pubKeyBech32Address,
}: {
addressPrefix: string;
coinType: string;
ethWallet?: boolean;
pubKeyBech32Address?: boolean;
},
) {
const storage = Container.get(storageToken);
const keychain = (await storage.get(KEYCHAIN)) as unknown as Keystore<T>;
Expand All @@ -225,12 +233,12 @@ export class KeyChain {
if (walletData.walletType === WALLETTYPE.PRIVATE_KEY) {
if (coinType === '60' || ethWallet) {
const hdPath = getHDPath(coinType, walletData.addressIndex.toString());
return EthWallet.generateWalletFromPvtKey(secret, { paths: [hdPath], addressPrefix });
return EthWallet.generateWalletFromPvtKey(secret, { paths: [hdPath], addressPrefix, pubKeyBech32Address });
}
return PvtKeyWallet.generateWallet(secret, addressPrefix);
} else {
const hdPath = getHDPath(coinType, walletData.addressIndex.toString());
return generateWalletFromMnemonic(secret, hdPath, addressPrefix, ethWallet);
return generateWalletFromMnemonic(secret, { hdPath, addressPrefix, ethWallet: !!ethWallet, pubKeyBech32Address });
}
}

Expand Down Expand Up @@ -286,11 +294,11 @@ export class KeyChain {
const addresses: Record<string, string> = {};
const pubKeys: Record<string, string> = {};
for (const chainInfo of chainsData) {
const wallet = generateWalletFromMnemonic(
mnemonic,
getHDPath(chainInfo.coinType, addressIndex.toString()),
chainInfo.addressPrefix,
);
const wallet = generateWalletFromMnemonic(mnemonic, {
hdPath: getHDPath(chainInfo.coinType, addressIndex.toString()),
addressPrefix: chainInfo.addressPrefix,
ethWallet: false,
});

const [account] = wallet.getAccounts();
if (account?.address && account?.pubkey) {
Expand Down
1 change: 1 addition & 0 deletions src/types/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PvtKeyWallet, Wallet } from '../key/wallet';
export type WalletOptions = {
paths: string[];
addressPrefix: string;
pubKeyBech32Address?: boolean;
};

export type LeapSigner = EthWallet | Wallet | PvtKeyWallet;
16 changes: 13 additions & 3 deletions tests/wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,20 @@ describe('generateMnemonic', () => {
).toThrow('Invalid private key');
});
test('generateWalletFromMnemonic', () => {
const wallet = generateWalletFromMnemonic(mnemonic, "m/44'/118'/0'/0/1", 'cosmos');
const wallet = generateWalletFromMnemonic(mnemonic, {
hdPath: "m/44'/118'/0'/0/1",
addressPrefix: 'cosmos',
ethWallet: false,
});
const accounts = wallet.getAccounts();
expect(accounts[0]?.address).toBe(referenceWallets.ref2.addresses.cosmos);
});
test('generateWalletFromMnemonic for cointype=60', () => {
const wallet = generateWalletFromMnemonic(mnemonic, "m/44'/60'/0'/0/1", 'evmos');
const wallet = generateWalletFromMnemonic(mnemonic, {
hdPath: "m/44'/60'/0'/0/1",
addressPrefix: 'evmos',
ethWallet: false,
});
const accounts = wallet.getAccounts();
expect(accounts[0]?.address).toBe(referenceWallets.ref2.addresses.evmos);
});
Expand All @@ -94,7 +102,9 @@ describe('generateMnemonic', () => {
expect(accounts[1]?.address).toBe(referenceWallets.ref2.addresses.evmos);
});
test('generateWalletFromMnemonic throws error if mnemonic is invalid', () => {
expect(() => generateWalletFromMnemonic('', "m/44'/118'/0'/0/0", 'cosmos')).toThrow('Invalid mnemonic');
expect(() =>
generateWalletFromMnemonic('', { hdPath: "m/44'/118'/0'/0/0", addressPrefix: 'cosmos', ethWallet: false }),
).toThrow('Invalid mnemonic');
});
test('generateWalletsFromMnemonic throws error if mnemonic is invalid', () => {
expect(() => generateWalletsFromMnemonic('', ["m/44'/118'/0'/0/0"], 'cosmos')).toThrow('Invalid mnemonic');
Expand Down

0 comments on commit e97c4d8

Please sign in to comment.