diff --git a/package.json b/package.json index 3cdb4f43..4814202a 100644 --- a/package.json +++ b/package.json @@ -36,11 +36,11 @@ "webpack-sources": "1.0.1" }, "dependencies": { - "@ledgerhq/hw-app-btc": "^4.12.0", - "@ledgerhq/hw-app-eth": "^4.12.0", - "@ledgerhq/hw-app-xrp": "^4.12.0", - "@ledgerhq/hw-transport": "^4.12.0", - "@ledgerhq/hw-transport-node-hid": "^4.12.0", + "@ledgerhq/hw-app-btc": "^4.13.0", + "@ledgerhq/hw-app-eth": "^4.13.0", + "@ledgerhq/hw-app-xrp": "^4.13.0", + "@ledgerhq/hw-transport": "^4.13.0", + "@ledgerhq/hw-transport-node-hid": "^4.13.0", "@ledgerhq/ledger-core": "1.4.5", "@ledgerhq/live-common": "2.29.0", "axios": "^0.18.0", diff --git a/src/bridge/EthereumJSBridge.js b/src/bridge/EthereumJSBridge.js index 20be763d..2696f69e 100644 --- a/src/bridge/EthereumJSBridge.js +++ b/src/bridge/EthereumJSBridge.js @@ -215,7 +215,7 @@ const EthereumBridge: WalletBridge = { xpub: '', freshAddress, freshAddressPath, - name: address.slice(32), + name: `Account ${index}`, balance, blockHeight: currentBlock.height, index, diff --git a/src/bridge/RippleJSBridge.js b/src/bridge/RippleJSBridge.js index 57463f2b..f02b9052 100644 --- a/src/bridge/RippleJSBridge.js +++ b/src/bridge/RippleJSBridge.js @@ -310,7 +310,7 @@ const RippleJSBridge: WalletBridge = { const account: $Exact = { id: accountId, xpub: '', - name: address.slice(0, 8), + name: `Account ${index}`, freshAddress, freshAddressPath, balance, diff --git a/src/commands/libcoreSignAndBroadcast.js b/src/commands/libcoreSignAndBroadcast.js index b5a92aad..d2627830 100644 --- a/src/commands/libcoreSignAndBroadcast.js +++ b/src/commands/libcoreSignAndBroadcast.js @@ -1,5 +1,6 @@ // @flow +import logger from 'logger' import type { AccountRaw, OperationRaw } from '@ledgerhq/live-common/lib/types' import Btc from '@ledgerhq/hw-app-btc' import { Observable } from 'rxjs' @@ -55,6 +56,84 @@ const cmd: Command = createCommand( }), ) +async function signTransaction({ + hwApp, + currencyId, + transaction, + sigHashType, + supportsSegwit, + isSegwit, + hasTimestamp, +}: { + hwApp: Btc, + currencyId: string, + transaction: *, + sigHashType: number, + supportsSegwit: boolean, + isSegwit: boolean, + hasTimestamp: boolean, +}) { + const additionals = [] + if (currencyId === 'bitcoin_cash' || currencyId === 'bitcoin_gold') additionals.push('bip143') + const rawInputs = transaction.getInputs() + + const inputs = await Promise.all( + rawInputs.map(async input => { + const rawPreviousTransaction = await input.getPreviousTransaction() + const hexPreviousTransaction = Buffer.from(rawPreviousTransaction).toString('hex') + const previousTransaction = hwApp.splitTransaction( + hexPreviousTransaction, + supportsSegwit, + hasTimestamp, + ) + const outputIndex = input.getPreviousOutputIndex() + const sequence = input.getSequence() + return [ + previousTransaction, + outputIndex, + undefined, // we don't use that TODO: document + sequence, // 0xffffffff, + ] + }), + ) + + const associatedKeysets = rawInputs.map(input => { + const derivationPaths = input.getDerivationPath() + return derivationPaths[0].toString() + }) + + const outputs = transaction.getOutputs() + + const output = outputs.find(output => { + const derivationPath = output.getDerivationPath() + if (derivationPath.isNull()) { + return false + } + const strDerivationPath = derivationPath.toString() + const derivationArr = strDerivationPath.split('/') + return derivationArr[derivationArr.length - 2] === '1' + }) + + const changePath = output ? output.getDerivationPath().toString() : undefined + const outputScriptHex = Buffer.from(transaction.serializeOutputs()).toString('hex') + const lockTime = transaction.getLockTime() + const initialTimestamp = hasTimestamp ? transaction.getTimestamp() : undefined + + const signedTransaction = await hwApp.createPaymentTransactionNew( + inputs, + associatedKeysets, + changePath, + outputScriptHex, + lockTime, + sigHashType, + isSegwit, + initialTimestamp, + additionals, + ) + + return signedTransaction +} + export async function doSignAndBroadcast({ account, transaction, @@ -74,7 +153,7 @@ export async function doSignAndBroadcast({ }): Promise { let njsAccount - const signedTransaction: ?string = await withDevice(deviceId)(async transport => { + const signedTransaction = await withDevice(deviceId)(async transport => { const hwApp = new Btc(transport) const WALLET_IDENTIFIER = await getWalletIdentifier({ @@ -103,21 +182,22 @@ export async function doSignAndBroadcast({ const builded = await transactionBuilder.build() if (isCancelled()) return null - const sigHashType = core.helpers.bytesToHex( + const sigHashType = Buffer.from( njsWalletCurrency.bitcoinLikeNetworkParameters.SigHash, - ) + ).toString('hex') - const hasTimestamp = njsWalletCurrency.bitcoinLikeNetworkParameters.UsesTimestampedTransaction + const hasTimestamp = !!njsWalletCurrency.bitcoinLikeNetworkParameters.UsesTimestampedTransaction // TODO: const timestampDelay = njsWalletCurrency.bitcoinLikeNetworkParameters.TimestampDelay const currency = getCryptoCurrencyById(account.currencyId) - return core.signTransaction({ + return signTransaction({ hwApp, + currencyId: account.currencyId, transaction: builded, - sigHashType: parseInt(sigHashType, 16).toString(), + sigHashType: parseInt(sigHashType, 16), supportsSegwit: !!currency.supportsSegwit, - isSegwit: account.isSegwit, + isSegwit: !!account.isSegwit, hasTimestamp, }) }) @@ -125,7 +205,12 @@ export async function doSignAndBroadcast({ if (!signedTransaction || isCancelled() || !njsAccount) return onSigned() - const txHash = await njsAccount.asBitcoinLikeAccount().broadcastRawTransaction(signedTransaction) + logger.log(signedTransaction) + + const txHash = await njsAccount + .asBitcoinLikeAccount() + .broadcastRawTransaction(Array.from(Buffer.from(signedTransaction, 'hex'))) + // NB we don't check isCancelled() because the broadcast is not cancellable now! onOperationBroadcasted({ id: txHash, diff --git a/yarn.lock b/yarn.lock index 286c7293..b85175b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1449,27 +1449,41 @@ version "0.6.3" resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.6.3.tgz#65682e68a82701c70eefb38d7f941a2c0bfa90de" -"@ledgerhq/hw-app-btc@^4.12.0", "@ledgerhq/hw-app-btc@^4.7.3": +"@ledgerhq/hw-app-btc@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-4.13.0.tgz#c2d093d94c6d59113e2150aedbb4b5b0c55d6826" + dependencies: + "@ledgerhq/hw-transport" "^4.13.0" + create-hash "^1.1.3" + +"@ledgerhq/hw-app-btc@^4.7.3": version "4.12.0" resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-4.12.0.tgz#deae3200dcb6eb196f05a7357c5499f3920e6c6f" dependencies: "@ledgerhq/hw-transport" "^4.12.0" create-hash "^1.1.3" -"@ledgerhq/hw-app-eth@^4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-4.12.0.tgz#8be54f2532ab816eb080905b12d7e1ff8b60840c" +"@ledgerhq/hw-app-eth@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-4.13.0.tgz#8a999263f2dd212e43bb1145018003f4bad52d33" dependencies: - "@ledgerhq/hw-transport" "^4.12.0" + "@ledgerhq/hw-transport" "^4.13.0" -"@ledgerhq/hw-app-xrp@^4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-xrp/-/hw-app-xrp-4.12.0.tgz#aeba3b5b2447e185811974312a3ed1b3eeb7a0f1" +"@ledgerhq/hw-app-xrp@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-xrp/-/hw-app-xrp-4.13.0.tgz#a38a1417297074da8d24cc0fef7a9a68c186a6ab" dependencies: - "@ledgerhq/hw-transport" "^4.12.0" + "@ledgerhq/hw-transport" "^4.13.0" bip32-path "0.4.2" -"@ledgerhq/hw-transport-node-hid@^4.12.0", "@ledgerhq/hw-transport-node-hid@^4.7.6": +"@ledgerhq/hw-transport-node-hid@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-4.13.0.tgz#86306ff10c860d8bbd002db3f4618078460e4b9a" + dependencies: + "@ledgerhq/hw-transport" "^4.13.0" + node-hid "^0.7.2" + +"@ledgerhq/hw-transport-node-hid@^4.7.6": version "4.12.0" resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-4.12.0.tgz#acd913904d0e600c681375c7bf5e0f9d5165a075" dependencies: @@ -1482,6 +1496,12 @@ dependencies: events "^2.0.0" +"@ledgerhq/hw-transport@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-4.13.0.tgz#463043200c96c91379318052ad4dbe8c80d95cf5" + dependencies: + events "^2.0.0" + "@ledgerhq/ledger-core@1.4.5": version "1.4.5" resolved "https://registry.yarnpkg.com/@ledgerhq/ledger-core/-/ledger-core-1.4.5.tgz#d3cf00ac07307d419b09e4cc1de8a8764ef16338"