diff --git a/src/commands/libcoreSignAndBroadcast.js b/src/commands/libcoreSignAndBroadcast.js index 3f0cc9e2..489f3759 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, @@ -152,56 +152,46 @@ export async function doSignAndBroadcast({ onSigned: () => void, onOperationBroadcasted: (optimisticOp: $Exact) => void, }): Promise { - let njsAccount + 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 signedTransaction = await withDevice(deviceId)(async transport => { - const hwApp = new Btc(transport) + const hasTimestamp = !!njsWalletCurrency.bitcoinLikeNetworkParameters.UsesTimestampedTransaction + // TODO: const timestampDelay = njsWalletCurrency.bitcoinLikeNetworkParameters.TimestampDelay - const WALLET_IDENTIFIER = await getWalletIdentifier({ - hwApp, - isSegwit: isSegwitAccount(account), - currencyId: account.currencyId, - devicePath: deviceId, - }) - - const njsWallet = await core.getWallet(WALLET_IDENTIFIER) - 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 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() 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