From 4f1f2364c2b90f7d9cb894728c0dcb491742992d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Thu, 14 Jun 2018 14:55:55 +0200 Subject: [PATCH 1/3] replace getWalletIdentifier by accountIdHelper for sign --- src/commands/libcoreSignAndBroadcast.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/commands/libcoreSignAndBroadcast.js b/src/commands/libcoreSignAndBroadcast.js index 3f0cc9e2..5a3a8169 100644 --- a/src/commands/libcoreSignAndBroadcast.js +++ b/src/commands/libcoreSignAndBroadcast.js @@ -10,7 +10,7 @@ import { isSegwitAccount } from 'helpers/bip32' import withLibcore from 'helpers/withLibcore' import { createCommand, Command } from 'helpers/ipc' import { withDevice } from 'helpers/deviceAccess' -import { getWalletIdentifier } from 'helpers/libcore' +import * as accountIdHelper from 'helpers/accountId' type BitcoinLikeTransaction = { amount: number, @@ -156,15 +156,8 @@ export async function doSignAndBroadcast({ const signedTransaction = await withDevice(deviceId)(async transport => { const hwApp = new Btc(transport) - - const WALLET_IDENTIFIER = await getWalletIdentifier({ - hwApp, - isSegwit: isSegwitAccount(account), - currencyId: account.currencyId, - devicePath: deviceId, - }) - - const njsWallet = await core.getWallet(WALLET_IDENTIFIER) + const { walletName } = accountIdHelper.decode(account.id) + const njsWallet = await core.getWallet(walletName) if (isCancelled()) return null njsAccount = await njsWallet.getAccount(account.index) if (isCancelled()) return null From de572e843cd4f88d77161259d3a97d6424947a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Thu, 14 Jun 2018 15:18:28 +0200 Subject: [PATCH 2/3] drop getWalletIdentifier & replace by encodeWalletName --- src/helpers/libcore.js | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/helpers/libcore.js b/src/helpers/libcore.js index 85dc35be..33ff6469 100644 --- a/src/helpers/libcore.js +++ b/src/helpers/libcore.js @@ -34,10 +34,9 @@ export function scanAccountsOnDevice(props: Props): Promise { const commonParams = { core, - hwApp, currencyId, onAccountScanned, - devicePath, + hwApp, } let allAccounts = [] @@ -62,22 +61,16 @@ export function scanAccountsOnDevice(props: Props): Promise { }) } -export async function getWalletIdentifier({ - hwApp, - isSegwit, +function encodeWalletName({ + publicKey, currencyId, - devicePath, + isSegwit, }: { - hwApp: Object, - isSegwit: boolean, + publicKey: string, currencyId: string, - devicePath: string, -}): Promise { - const isVerify = false - const deviceIdentifiers = await hwApp.getWalletPublicKey(devicePath, isVerify, isSegwit) - const { publicKey } = deviceIdentifiers - const WALLET_IDENTIFIER = `${publicKey}__${currencyId}${isSegwit ? '_segwit' : ''}` - return WALLET_IDENTIFIER + isSegwit: boolean, +}) { + return `${publicKey}__${currencyId}${isSegwit ? '_segwit' : ''}` } async function scanAccountsOnDeviceBySegwit({ @@ -85,7 +78,6 @@ async function scanAccountsOnDeviceBySegwit({ hwApp, currencyId, onAccountScanned, - devicePath, isSegwit, showNewAccount, }: { @@ -93,15 +85,19 @@ async function scanAccountsOnDeviceBySegwit({ hwApp: Object, currencyId: string, onAccountScanned: AccountRaw => void, - devicePath: string, - isSegwit: boolean, + isSegwit: boolean, // FIXME all segwit to change to 'purpose' showNewAccount: boolean, }): Promise { - // compute wallet identifier - const WALLET_IDENTIFIER = await getWalletIdentifier({ hwApp, isSegwit, currencyId, devicePath }) + const { coinType } = getCryptoCurrencyById(currencyId) + const { publicKey } = await hwApp.getWalletPublicKey( + `${isSegwit ? '49' : '44'}'/${coinType}'`, + false, + isSegwit, + ) + const walletName = encodeWalletName({ publicKey, currencyId, isSegwit }) // retrieve or create the wallet - const wallet = await getOrCreateWallet(core, WALLET_IDENTIFIER, currencyId, isSegwit) + const wallet = await getOrCreateWallet(core, walletName, currencyId, isSegwit) const accountsCount = await wallet.getAccountCount() // recursively scan all accounts on device on the given app From 4d9826fec4f0bebea07b9e035fc392a7fc2b897d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Thu, 14 Jun 2018 15:36:48 +0200 Subject: [PATCH 3/3] minimize need of the device in sign and broadcast --- src/commands/libcoreSignAndBroadcast.js | 71 ++++++++++++------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/src/commands/libcoreSignAndBroadcast.js b/src/commands/libcoreSignAndBroadcast.js index 5a3a8169..489f3759 100644 --- a/src/commands/libcoreSignAndBroadcast.js +++ b/src/commands/libcoreSignAndBroadcast.js @@ -152,49 +152,46 @@ export async function doSignAndBroadcast({ onSigned: () => void, onOperationBroadcasted: (optimisticOp: $Exact) => void, }): Promise { - let njsAccount - - const signedTransaction = await withDevice(deviceId)(async transport => { - const hwApp = new Btc(transport) - const { walletName } = accountIdHelper.decode(account.id) - const njsWallet = await core.getWallet(walletName) - if (isCancelled()) return null - njsAccount = await njsWallet.getAccount(account.index) - if (isCancelled()) return null - const bitcoinLikeAccount = njsAccount.asBitcoinLikeAccount() - const njsWalletCurrency = njsWallet.getCurrency() - const amount = core.createAmount(njsWalletCurrency, transaction.amount) - const fees = core.createAmount(njsWalletCurrency, transaction.feePerByte) - const transactionBuilder = bitcoinLikeAccount.buildTransaction() - - // TODO: check if is valid address. if not, it will fail silently on invalid - - transactionBuilder.sendToAddress(amount, transaction.recipient) - // TODO: don't use hardcoded value for sequence (and first also maybe) - transactionBuilder.pickInputs(0, 0xffffff) - transactionBuilder.setFeesPerByte(fees) - - const builded = await transactionBuilder.build() - if (isCancelled()) return null - const sigHashType = Buffer.from( - njsWalletCurrency.bitcoinLikeNetworkParameters.SigHash, - ).toString('hex') - - const hasTimestamp = !!njsWalletCurrency.bitcoinLikeNetworkParameters.UsesTimestampedTransaction - // TODO: const timestampDelay = njsWalletCurrency.bitcoinLikeNetworkParameters.TimestampDelay - - const currency = getCryptoCurrencyById(account.currencyId) - - return signTransaction({ - hwApp, + const { walletName } = accountIdHelper.decode(account.id) + const njsWallet = await core.getWallet(walletName) + if (isCancelled()) return + const njsAccount = await njsWallet.getAccount(account.index) + if (isCancelled()) return + const bitcoinLikeAccount = njsAccount.asBitcoinLikeAccount() + const njsWalletCurrency = njsWallet.getCurrency() + const amount = core.createAmount(njsWalletCurrency, transaction.amount) + const fees = core.createAmount(njsWalletCurrency, transaction.feePerByte) + const transactionBuilder = bitcoinLikeAccount.buildTransaction() + + // TODO: check if is valid address. if not, it will fail silently on invalid + + transactionBuilder.sendToAddress(amount, transaction.recipient) + // TODO: don't use hardcoded value for sequence (and first also maybe) + transactionBuilder.pickInputs(0, 0xffffff) + transactionBuilder.setFeesPerByte(fees) + + const builded = await transactionBuilder.build() + if (isCancelled()) return + const sigHashType = Buffer.from(njsWalletCurrency.bitcoinLikeNetworkParameters.SigHash).toString( + 'hex', + ) + + const hasTimestamp = !!njsWalletCurrency.bitcoinLikeNetworkParameters.UsesTimestampedTransaction + // TODO: const timestampDelay = njsWalletCurrency.bitcoinLikeNetworkParameters.TimestampDelay + + const currency = getCryptoCurrencyById(account.currencyId) + + const signedTransaction = await withDevice(deviceId)(async transport => + signTransaction({ + hwApp: new Btc(transport), currencyId: account.currencyId, transaction: builded, sigHashType: parseInt(sigHashType, 16), supportsSegwit: !!currency.supportsSegwit, isSegwit: isSegwitAccount(account), hasTimestamp, - }) - }) + }), + ) if (!signedTransaction || isCancelled() || !njsAccount) return onSigned()