Skip to content

Commit

Permalink
Merge pull request #44 from leapwallet/fix/btc-wallet
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
baryon2 authored Nov 22, 2024
2 parents 4cba6ca + 7f61916 commit 724afd7
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 22 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.5-beta.13",
"version": "0.2.5-beta.14",
"description": "A javascript library for crypto key management",
"scripts": {
"test:coverage": "nyc mocha",
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ export * from './utils/init-crypto';
export * from './key/wallet-utils';
export * from './utils/get-hdpath';

export { NETWORK, TEST_NETWORK, Transaction } from '@scure/btc-signer';
export { NETWORK, TEST_NETWORK, Transaction, Address as BtcAddress } from '@scure/btc-signer';
8 changes: 5 additions & 3 deletions src/key/wallet-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export function generateWalletFromMnemonic(
switch (coinType) {
case "60'":
return EthWallet.generateWalletFromMnemonic(mnemonic, { paths: [hdPath], addressPrefix, pubKeyBech32Address });
case "0'": {
case "0'":
case "1'": {
if (!btcNetwork) throw new Error('Cannot create btc wallet. Please provide network');
return BtcWalletHD.generateWalletFromMnemonic(mnemonic, { paths: [hdPath], addressPrefix, network: btcNetwork });
}
Expand Down Expand Up @@ -80,7 +81,8 @@ export function generateWalletsFromMnemonic(
switch (refCoinType) {
case '60':
return EthWallet.generateWalletFromMnemonic(mnemonic, { paths, addressPrefix: prefix });
case '0': {
case '0':
case '1': {
if (!btcNetwork) throw new Error('Cannot create btc wallet. Please provide network');
return BtcWalletHD.generateWalletFromMnemonic(mnemonic, { paths, addressPrefix: prefix, network: btcNetwork });
}
Expand Down Expand Up @@ -108,7 +110,7 @@ export function generateWalletFromPrivateKey(
paths: [hdPath],
addressPrefix: prefix,
});
} else if (coinType === "0'") {
} else if (coinType === "0'" || coinType === "1'") {
if (!btcNetwork) throw new Error('Unable to generate key. Please provide btc network in chain info config');
wallet = new BtcWalletPk(privateKey, {
paths: [hdPath],
Expand Down
6 changes: 3 additions & 3 deletions src/keychain/keychain.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EthWallet } from '../key/eth-wallet';
import getHDPath, { getFullHDPath } from '../utils/get-hdpath';
import getHDPath, { getFullHDPath, isBtcCoinType } from '../utils/get-hdpath';
import { PvtKeyWallet } from '../key/wallet';

import { Container } from 'typedi';
Expand Down Expand Up @@ -241,7 +241,7 @@ export class KeyChain {
if (coinType === '60' || ethWallet) {
const hdPath = getHDPath(coinType, walletData.addressIndex.toString());
return EthWallet.generateWalletFromPvtKey(secret, { paths: [hdPath], addressPrefix, pubKeyBech32Address });
} else if (coinType === '0') {
} else if (isBtcCoinType(coinType)) {
if (!btcNetwork) throw new Error('Cannot create btc wallet. Please provide network');
return new BtcWalletPk(secret, {
paths: [getHDPath(coinType, walletData.addressIndex.toString())],
Expand All @@ -251,7 +251,7 @@ export class KeyChain {
}
return PvtKeyWallet.generateWallet(secret, addressPrefix);
} else {
const purpose = coinType === '0' ? '84' : '44';
const purpose = isBtcCoinType(coinType) ? '84' : '44';
const hdPath = getFullHDPath(purpose, coinType, walletData.addressIndex.toString());
return generateWalletFromMnemonic(secret, {
hdPath,
Expand Down
4 changes: 4 additions & 0 deletions src/utils/get-hdpath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ export default function getHDPath(coinType = '118', index = '0', account = '0',
export function getFullHDPath(purpose = '44', coinType = '0', index = '0', account = '0', chain = '0') {
return `m/${purpose}'/${coinType}'/${account}'/${chain}/${index}`;
}

export function isBtcCoinType(coinType: string) {
return coinType === '1' || coinType === '0';
}
12 changes: 6 additions & 6 deletions test/btc-wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { setBip39 } from '../src/crypto/bip39/bip39-token';
import { ripemd160Token, sha256Token } from '../src/crypto/hashes/hashes';
import { BtcWalletHD, BtcWalletPk } from '../src/key/btc-wallet';
import expect from 'expect.js';
import { addresses, btcPrivatekey, mnemonic } from './mockdata';
import { addresses, btcPrivatekey, mnemonic, sbtcPrivatekey } from './mockdata';
import { NETWORK, TEST_NETWORK } from '@scure/btc-signer';

beforeEach(() => {
Expand All @@ -34,13 +34,13 @@ describe('generate btc wallet', () => {
});
it('generates correct signet wallet', () => {
const wallet = BtcWalletHD.generateWalletFromMnemonic(mnemonic, {
addressPrefix: 'bc1q',
paths: ["m/84'/0'/0'/0/0"],
addressPrefix: 'tb1q',
paths: ["m/84'/1'/0'/0/0"],
network: TEST_NETWORK,
});
const accounts = wallet.getAccountsWithPrivKey();

const expectedAccount = 'tb1qd5xpfp9zp8q696pu3sz7ej2wrk2wn6348egyjw';
const expectedAccount = addresses.signet;
if (accounts[0]) {
expect(accounts[0].address).to.be(expectedAccount);
}
Expand All @@ -58,9 +58,9 @@ describe('generate btc wallet', () => {
});

it('generates correct signet wallet from private key', () => {
const wallet = new BtcWalletPk(btcPrivatekey, {
const wallet = new BtcWalletPk(sbtcPrivatekey, {
addressPrefix: 'tb1q',
paths: ["m/84'/0'/0'/0/0"],
paths: ["m/84'/1'/0'/0/0"],
network: TEST_NETWORK,
});

Expand Down
15 changes: 8 additions & 7 deletions test/mockdata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NETWORK, TEST_NETWORK } from '@scure/btc-signer';
export const mnemonic = 'talk chat police leisure hill remember extra struggle treat utility before wine';
export const privateKey = '0x8e754bd2427d31124df0f0717eb0d4289b87ca1f789d27e41b12523879aeecf1';
export const btcPrivatekey = 'a29da5e16cf8a7a4fe90dc9287c3338e6726b8bd4c1e9a8ab40d87200de08ffb';
export const sbtcPrivatekey = 'acc42e2d3fb504915180bae5d001e818f3304b970b2a145ebc252faf2fbd8867';

export const addresses = {
secret: 'secret18qya73yjlt28hhc3yefu3j97kgpyjj9rfd46d6',
Expand All @@ -12,7 +13,7 @@ export const addresses = {
evmos: 'evmos1reqqp5jum0lgyjh33nyvus8dlyzspk9aw50w3r',
injective: 'inj1reqqp5jum0lgyjh33nyvus8dlyzspk9axufyen',
bitcoin: 'bc1qd5xpfp9zp8q696pu3sz7ej2wrk2wn634dlnhfa',
signet: 'tb1qd5xpfp9zp8q696pu3sz7ej2wrk2wn6348egyjw',
signet: 'tb1qp63mr992cpwspcjnysdfhstj6jaqykrs64yywn',
};

export const referenceWallets = {
Expand All @@ -26,7 +27,7 @@ export const referenceWallets = {
juno: 'juno1nqcal4r4qgfj9hhazrfpu72fx0ccdv35cgxu6d',
osmosis: 'osmo1nqcal4r4qgfj9hhazrfpu72fx0ccdv35xpkhtr',
secret: 'secret1gcf3qag3zf0k9sd759ttuuq287p00g4kewjdwc',
signet: 'tb1qd5xpfp9zp8q696pu3sz7ej2wrk2wn6348egyjw',
signet: 'tb1qp63mr992cpwspcjnysdfhstj6jaqykrs64yywn',
},
colorIndex: 0,
name: 'testwallet',
Expand All @@ -38,7 +39,7 @@ export const referenceWallets = {
osmosis: 'AwxYytPNgUq91tLoRiGBP6MGEcsghnVTeMcLKcoPSfjW',
secret: 'AnQhTZmbQZXa9MY3KhYdEE1OabdLBtEAbG/wgj0SzBEV',
bitcoin: 'AjQmZKXn3epwg10mUNuHUF1SxWLS+06AA1v4um9x8//2',
signet: 'AjQmZKXn3epwg10mUNuHUF1SxWLS+06AA1v4um9x8//2',
signet: 'AuLI5ATf2xgkFbHojyMsSQ2qbnvZoVyfu9JACxiZz8ji',
},
walletType: 0,
},
Expand All @@ -52,7 +53,7 @@ export const referenceWallets = {
osmosis: 'osmo1rjtukzmqtlh2u20atc9pjefk55y0h6j2v9wm4q',
secret: 'secret1v7pzm2xdytc75dxx893fnd4te80qh6nw2k9czh',
bitcoin: 'bc1qpx6cas6wg4gtpcmfke626va4kpx9m4s5cx03ff',
signet: 'tb1qpx6cas6wg4gtpcmfke626va4kpx9m4s5jq5zj6',
signet: 'tb1qh9d6qr7twdk7dh5tsw7mqxl5yvxskrcs80gppq',
},
colorIndex: 1,
name: 'Wallet 2',
Expand All @@ -64,7 +65,7 @@ export const referenceWallets = {
osmosis: 'AqYABZ4+Zqqbx7zZfctmtRQs882J15WfRz3Go9QggsIA',
secret: 'AlvxQlaPKJI+25bX8I6TD6EaGbZl1f6Ngu/E9nO4KZCn',
bitcoin: 'A3hQ226XkTCvpEXC3KqxLEZANyNjyMmJhIm8rDwX/EKE',
signet: 'A3hQ226XkTCvpEXC3KqxLEZANyNjyMmJhIm8rDwX/EKE',
signet: 'A0Ygge2Va8zePPPtwVyb8dt5Lf5fH9SvPxUdVylD5+cC',
},
walletType: 0,
},
Expand All @@ -89,7 +90,7 @@ export const coinTypes = {
evmos: 60,
injective: 60,
bitcoin: 0,
signet: 0,
signet: 1,
};

export const chainInfos: Record<
Expand Down Expand Up @@ -128,7 +129,7 @@ export const chainInfos: Record<
},
signet: {
addressPrefix: addressPrefixes.signet,
coinType: coinTypes.bitcoin,
coinType: coinTypes.signet,
useBip84: true,
btcNetwork: TEST_NETWORK,
},
Expand Down
2 changes: 1 addition & 1 deletion test/wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ beforeEach(() => {
describe('generateMnemonic', () => {
it('generates wallet', () => {
const chainData = Object.entries(chainInfos).filter(
([, chainInfo]) => chainInfo.coinType !== 60 && chainInfo.coinType !== 0,
([, chainInfo]) => chainInfo.coinType !== 60 && chainInfo.coinType !== 0 && chainInfo.coinType !== 1,
);

for (const [key, chainInfo] of chainData) {
Expand Down

0 comments on commit 724afd7

Please sign in to comment.