diff --git a/packages/engine/src/vaults/impl/btc/KeyringImported.ts b/packages/engine/src/vaults/impl/btc/KeyringImported.ts index a8837571609..d150bed045b 100644 --- a/packages/engine/src/vaults/impl/btc/KeyringImported.ts +++ b/packages/engine/src/vaults/impl/btc/KeyringImported.ts @@ -8,7 +8,7 @@ import { OneKeyInternalError } from '../../../errors'; import { AccountType } from '../../../types/account'; import { AddressEncodings } from '../../utils/btcForkChain/types'; import { - getBitcoinBip32, + getBip32FromBase58, initBitcoinEcc, } from '../../utils/btcForkChain/utils'; @@ -80,9 +80,11 @@ export class KeyringImported extends KeyringImportedBtcFork { addressEncoding, ); - const node = getBitcoinBip32() - .fromBase58(privateKeyString) - .derivePath(firstAddressRelPath); + const node = getBip32FromBase58({ + coinType: COIN_TYPE, + key: privateKeyString, + }).derivePath(firstAddressRelPath); + pub = node.publicKey.toString('hex'); return Promise.resolve([ diff --git a/packages/engine/src/vaults/utils/btcForkChain/KeyringImported.ts b/packages/engine/src/vaults/utils/btcForkChain/KeyringImported.ts index 204222dc78c..0da06c4c678 100644 --- a/packages/engine/src/vaults/utils/btcForkChain/KeyringImported.ts +++ b/packages/engine/src/vaults/utils/btcForkChain/KeyringImported.ts @@ -1,8 +1,8 @@ import bs58check from 'bs58check'; import type { ExtendedKey } from '@onekeyhq/engine/src/secret'; -import { BaseBip32KeyDeriver } from '@onekeyhq/engine/src/secret/bip32'; import type { Bip32KeyDeriver } from '@onekeyhq/engine/src/secret/bip32'; +import { BaseBip32KeyDeriver } from '@onekeyhq/engine/src/secret/bip32'; import { secp256k1 } from '@onekeyhq/engine/src/secret/curves'; import { decrypt, @@ -18,7 +18,7 @@ import { AccountType } from '../../../types/account'; import { BtcMessageTypes } from '../../../types/message'; import { KeyringImportedBase } from '../../keyring/KeyringImportedBase'; -import { getBitcoinBip32, getBitcoinECPair, initBitcoinEcc } from './utils'; +import { getBip32FromBase58, getBitcoinECPair, initBitcoinEcc } from './utils'; import type { DBUTXOAccount } from '../../../types/account'; import type { IUnsignedMessageBtc } from '../../impl/btc/types'; @@ -180,6 +180,13 @@ export class KeyringImported extends KeyringImportedBase { ): Promise { initBitcoinEcc(); debugLogger.common.info('BTCFork signMessage', messages); + + const provider = await ( + this.vault as unknown as BTCForkVault + ).getProvider(); + + const COIN_TYPE = (this.vault as unknown as BTCForkVault).getCoinType(); + const { password = '' } = options; const account = await this.engine.getAccount( @@ -189,14 +196,16 @@ export class KeyringImported extends KeyringImportedBase { const [encryptedXprv] = Object.values(await this.getPrivateKeys(password)); const xprv = bs58check.encode(decrypt(password, encryptedXprv)); - const node = getBitcoinBip32().fromBase58(xprv).derivePath('0/0'); + + const node = getBip32FromBase58({ + coinType: COIN_TYPE, + key: xprv, + }).derivePath('0/0'); + const keyPair = getBitcoinECPair().fromWIF(node.toWIF()); const network = await this.getNetwork(); const path = `${account.path}/0/0`; - const provider = await ( - this.vault as unknown as BTCForkVault - ).getProvider(); const result: Buffer[] = []; diff --git a/packages/engine/src/vaults/utils/btcForkChain/provider/networks.ts b/packages/engine/src/vaults/utils/btcForkChain/provider/networks.ts index cbcc3be26a4..cce01eea92a 100644 --- a/packages/engine/src/vaults/utils/btcForkChain/provider/networks.ts +++ b/packages/engine/src/vaults/utils/btcForkChain/provider/networks.ts @@ -1,7 +1,10 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/unbound-method */ import * as BitcoinJS from 'bitcoinjs-lib'; import typeforce from 'typeforce'; +import type { IBtcForkImpls } from '@onekeyhq/shared/src/engine/engineConsts'; + import { AddressEncodings } from '../types'; export interface Network extends BitcoinJS.Network { @@ -167,22 +170,26 @@ const dash = { wif: 0xcc, }; -const extendedNetworks: Record = { +const extendedNetworks: Record = { btc, tbtc, - rbtc, ltc, bch, doge, - btg, - dgb, - nmc, - vtc, - dash, + // TODO not support impl yet + // rbtc, + // btg, + // dgb, + // nmc, + // vtc, + // dash, }; -const getNetwork = (chainCode: string): Network => { - const network = extendedNetworks[chainCode]; +export const allBtcForkNetworks = extendedNetworks; + +// check fromDBNetworkToChainInfo +const getNetwork = (chainCode: IBtcForkImpls | string): Network => { + const network = extendedNetworks[chainCode as IBtcForkImpls]; if (typeof network === 'undefined') { throw new Error(`Network not found. chainCode: ${chainCode}`); } diff --git a/packages/engine/src/vaults/utils/btcForkChain/utils/index.ts b/packages/engine/src/vaults/utils/btcForkChain/utils/index.ts index f6f81ec592f..9648673f790 100644 --- a/packages/engine/src/vaults/utils/btcForkChain/utils/index.ts +++ b/packages/engine/src/vaults/utils/btcForkChain/utils/index.ts @@ -1,20 +1,27 @@ import { BIP32Factory } from 'bip32'; import * as BitcoinJS from 'bitcoinjs-lib'; +import bs58check from 'bs58check'; import { ECPairFactory } from 'ecpair'; +import { cloneDeep } from 'lodash'; + +import { IMPL_BTC, IMPL_TBTC } from '@onekeyhq/shared/src/engine/engineConsts'; import { NotImplemented } from '../../../../errors'; +import { getImplByCoinType } from '../../../../managers/impl'; import { Tx } from '../../../impl/btc/inscribe/sdk'; +import { allBtcForkNetworks } from '../provider/networks'; import ecc from '../provider/nobleSecp256k1Wrapper'; import { AddressEncodings } from '../types'; import type { DBUTXOAccount } from '../../../../types/account'; +import type { Network } from '../provider/networks'; import type { Networks } from '@cmdcode/tapscript'; import type { BIP32API } from 'bip32/types/bip32'; import type { TinySecp256k1Interface } from 'bitcoinjs-lib/src/types'; import type { ECPairAPI } from 'ecpair/src/ecpair'; -export * from './tapRootAccountUtils'; export * from './coinSelectUtils'; +export * from './tapRootAccountUtils'; type IAccountDefault = { namePrefix: string; @@ -131,3 +138,48 @@ export function getBitcoinECPair() { } return ECPair; } + +export function getBip32FromBase58({ + coinType, + key, +}: { + coinType: string; + key: string; +}) { + const impl = getImplByCoinType(coinType); + if (!impl) { + throw new Error(`impl not found from coinType: ${coinType}`); + } + let network: Network | undefined; + if (impl === IMPL_BTC) { + network = allBtcForkNetworks.btc; + } + if (impl === IMPL_TBTC) { + network = allBtcForkNetworks.tbtc; + } + if (!network) { + throw new Error(`network not support: ${impl}`); + } + + // const accountNameInfoMap = getAccountNameInfoByImpl(IMPL_BTC); + // const accountNameInfo = Object.values(accountNameInfoMap); + + const buffer = bs58check.decode(key); + const version = buffer.readUInt32BE(0); + + const versionByteOptions = [ + network.bip32, + ...Object.values(network.segwitVersionBytes || {}), + ]; + let bip32Info = cloneDeep(network.bip32); + for (const versionByte of versionByteOptions) { + if (versionByte.private === version || versionByte.public === version) { + bip32Info = cloneDeep(versionByte); + break; + } + } + const newNetwork = cloneDeep(network); + newNetwork.bip32 = bip32Info; + const bip32Api = getBitcoinBip32().fromBase58(key, newNetwork); + return bip32Api; +} diff --git a/packages/kit-bg/src/services/ServiceBootstrap.ts b/packages/kit-bg/src/services/ServiceBootstrap.ts index d67f143025e..5f1ebcbacdb 100644 --- a/packages/kit-bg/src/services/ServiceBootstrap.ts +++ b/packages/kit-bg/src/services/ServiceBootstrap.ts @@ -9,7 +9,7 @@ import { } from '@onekeyhq/engine/src/managers/impl'; import { getPresetNetworks } from '@onekeyhq/engine/src/presets'; import type { DBUTXOAccount } from '@onekeyhq/engine/src/types/account'; -import { getBitcoinBip32 } from '@onekeyhq/engine/src/vaults/utils/btcForkChain/utils'; +import { getBip32FromBase58 } from '@onekeyhq/engine/src/vaults/utils/btcForkChain/utils'; import { setAccountDerivationDbMigrationVersion, setMigrationVersions, @@ -27,6 +27,7 @@ import { COINTYPE_BTC, COINTYPE_COSMOS, COINTYPE_SUI, + COINTYPE_TBTC, FIX_BTC_PUB_DB_MIGRATION_VERSION, FIX_COSMOS_TEMPLATE_DB_MIGRATION_VERSION, IMPL_COSMOS, @@ -464,16 +465,19 @@ export default class ServiceBootstrap extends ServiceBase { // check all hd/hw/imported btc accounts const accounts = allAccounts.filter( (account) => - account.coinType === COINTYPE_BTC && + [COINTYPE_BTC, COINTYPE_TBTC].includes(account.coinType) && !isWatchingAccount({ accountId: account.id }), ) as DBUTXOAccount[]; for (const account of accounts) { debugLogger.common.info( `migrate account: ${JSON.stringify(account)}`, ); - const node = getBitcoinBip32() - .fromBase58(account.xpub) - .derivePath('0/0'); + + const node = getBip32FromBase58({ + coinType: account.coinType, + key: account.xpub, + }).derivePath('0/0'); + const pub = node.publicKey.toString('hex'); // @ts-ignore diff --git a/packages/shared/src/engine/engineConsts.ts b/packages/shared/src/engine/engineConsts.ts index 3b790905228..1ba5f7c9845 100644 --- a/packages/shared/src/engine/engineConsts.ts +++ b/packages/shared/src/engine/engineConsts.ts @@ -83,6 +83,13 @@ const COINTYPE_LIGHTNING_TESTNET = '81297820149140'; const IMPL_ALLNETWORKS = 'all'; const COINTYPE_ALLNETWORKS = '0000'; +export type IBtcForkImpls = + | typeof IMPL_BTC + | typeof IMPL_TBTC + | typeof IMPL_LTC + | typeof IMPL_BCH + | typeof IMPL_DOGE; + const SUPPORTED_IMPLS = new Set([ IMPL_EVM, IMPL_NEAR, @@ -167,59 +174,59 @@ function getSupportedImpls() { } export { - SEPERATOR, - INDEX_PLACEHOLDER, - IMPL_EVM, - COINTYPE_ETH, - COINTYPE_ETC, - IMPL_SOL, - COINTYPE_SOL, - IMPL_ALGO, + COINTYPE_ADA, COINTYPE_ALGO, - IMPL_NEAR, + COINTYPE_ALLNETWORKS, + COINTYPE_APTOS, + COINTYPE_BCH, + COINTYPE_BTC, + COINTYPE_CFX, + COINTYPE_COSMOS, + COINTYPE_DOGE, + COINTYPE_DOT, + COINTYPE_ETC, + COINTYPE_ETH, + COINTYPE_FIL, + COINTYPE_KASPA, + COINTYPE_LIGHTNING, + COINTYPE_LIGHTNING_TESTNET, + COINTYPE_LTC, COINTYPE_NEAR, - IMPL_STC, + COINTYPE_NEXA, + COINTYPE_SOL, COINTYPE_STC, - IMPL_CFX, - COINTYPE_CFX, - IMPL_BTC, - COINTYPE_BTC, - IMPL_TBTC, + COINTYPE_SUI, COINTYPE_TBTC, - IMPL_TRON, COINTYPE_TRON, + COINTYPE_XMR, + COINTYPE_XRP, + IMPL_ADA, + IMPL_ALGO, + IMPL_ALLNETWORKS, IMPL_APTOS, - COINTYPE_APTOS, - IMPL_DOGE, - COINTYPE_DOGE, - IMPL_LTC, - COINTYPE_LTC, IMPL_BCH, - COINTYPE_BCH, - IMPL_XRP, - COINTYPE_XRP, + IMPL_BTC, + IMPL_CFX, IMPL_COSMOS, - COINTYPE_COSMOS, - IMPL_ADA, - COINTYPE_ADA, - IMPL_SUI, - COINTYPE_SUI, - IMPL_FIL, - COINTYPE_FIL, + IMPL_DOGE, IMPL_DOT, - COINTYPE_DOT, - IMPL_XMR, - COINTYPE_XMR, + IMPL_EVM, + IMPL_FIL, IMPL_KASPA, - COINTYPE_KASPA, - IMPL_NEXA, - COINTYPE_NEXA, IMPL_LIGHTNING, - COINTYPE_LIGHTNING, IMPL_LIGHTNING_TESTNET, - COINTYPE_LIGHTNING_TESTNET, - IMPL_ALLNETWORKS, - COINTYPE_ALLNETWORKS, + IMPL_LTC, + IMPL_NEAR, + IMPL_NEXA, + IMPL_SOL, + IMPL_STC, + IMPL_SUI, + IMPL_TBTC, + IMPL_TRON, + IMPL_XMR, + IMPL_XRP, + INDEX_PLACEHOLDER, + SEPERATOR, getSupportedImpls, };