|
|
@ -2,11 +2,11 @@ |
|
|
|
|
|
|
|
import logger from 'logger' |
|
|
|
import { BigNumber } from 'bignumber.js' |
|
|
|
import type { AccountRaw, OperationRaw } from '@ledgerhq/live-common/lib/types' |
|
|
|
import type { OperationRaw } from '@ledgerhq/live-common/lib/types' |
|
|
|
import Btc from '@ledgerhq/hw-app-btc' |
|
|
|
import { Observable } from 'rxjs' |
|
|
|
import { getCryptoCurrencyById } from '@ledgerhq/live-common/lib/helpers/currencies' |
|
|
|
import { isSegwitAccount } from 'helpers/bip32' |
|
|
|
import { isSegwitPath } from 'helpers/bip32' |
|
|
|
import { libcoreAmountToBigNumber, bigNumberToLibcoreAmount } from 'helpers/libcore' |
|
|
|
|
|
|
|
import withLibcore from 'helpers/withLibcore' |
|
|
@ -21,7 +21,12 @@ type BitcoinLikeTransaction = { |
|
|
|
} |
|
|
|
|
|
|
|
type Input = { |
|
|
|
account: AccountRaw, // FIXME there is no reason we send the whole AccountRaw
|
|
|
|
accountId: string, |
|
|
|
currencyId: string, |
|
|
|
xpub: string, |
|
|
|
freshAddress: string, |
|
|
|
freshAddressPath: string, |
|
|
|
index: number, |
|
|
|
transaction: BitcoinLikeTransaction, |
|
|
|
deviceId: string, |
|
|
|
} |
|
|
@ -32,13 +37,18 @@ type Result = { type: 'signed' } | { type: 'broadcasted', operation: OperationRa |
|
|
|
|
|
|
|
const cmd: Command<Input, Result> = createCommand( |
|
|
|
'libcoreSignAndBroadcast', |
|
|
|
({ account, transaction, deviceId }) => |
|
|
|
({ accountId, currencyId, xpub, freshAddress, freshAddressPath, index, transaction, deviceId }) => |
|
|
|
Observable.create(o => { |
|
|
|
let unsubscribed = false |
|
|
|
const isCancelled = () => unsubscribed |
|
|
|
withLibcore(core => |
|
|
|
doSignAndBroadcast({ |
|
|
|
account, |
|
|
|
accountId, |
|
|
|
currencyId, |
|
|
|
xpub, |
|
|
|
freshAddress, |
|
|
|
freshAddressPath, |
|
|
|
index, |
|
|
|
transaction, |
|
|
|
deviceId, |
|
|
|
core, |
|
|
@ -151,7 +161,12 @@ async function signTransaction({ |
|
|
|
} |
|
|
|
|
|
|
|
export async function doSignAndBroadcast({ |
|
|
|
account, |
|
|
|
accountId, |
|
|
|
currencyId, |
|
|
|
xpub, |
|
|
|
freshAddress, |
|
|
|
freshAddressPath, |
|
|
|
index, |
|
|
|
transaction, |
|
|
|
deviceId, |
|
|
|
core, |
|
|
@ -159,7 +174,12 @@ export async function doSignAndBroadcast({ |
|
|
|
onSigned, |
|
|
|
onOperationBroadcasted, |
|
|
|
}: { |
|
|
|
account: AccountRaw, |
|
|
|
accountId: string, |
|
|
|
currencyId: string, |
|
|
|
xpub: string, |
|
|
|
freshAddress: string, |
|
|
|
freshAddressPath: string, |
|
|
|
index: number, |
|
|
|
transaction: BitcoinLikeTransaction, |
|
|
|
deviceId: string, |
|
|
|
core: *, |
|
|
@ -167,10 +187,10 @@ export async function doSignAndBroadcast({ |
|
|
|
onSigned: () => void, |
|
|
|
onOperationBroadcasted: (optimisticOp: $Exact<OperationRaw>) => void, |
|
|
|
}): Promise<void> { |
|
|
|
const { walletName } = accountIdHelper.decode(account.id) |
|
|
|
const { walletName } = accountIdHelper.decode(accountId) |
|
|
|
const njsWallet = await core.getPoolInstance().getWallet(walletName) |
|
|
|
if (isCancelled()) return |
|
|
|
const njsAccount = await njsWallet.getAccount(account.index) |
|
|
|
const njsAccount = await njsWallet.getAccount(index) |
|
|
|
if (isCancelled()) return |
|
|
|
const bitcoinLikeAccount = njsAccount.asBitcoinLikeAccount() |
|
|
|
const njsWalletCurrency = njsWallet.getCurrency() |
|
|
@ -194,16 +214,16 @@ export async function doSignAndBroadcast({ |
|
|
|
const hasTimestamp = !!njsWalletCurrency.bitcoinLikeNetworkParameters.UsesTimestampedTransaction |
|
|
|
// TODO: const timestampDelay = njsWalletCurrency.bitcoinLikeNetworkParameters.TimestampDelay
|
|
|
|
|
|
|
|
const currency = getCryptoCurrencyById(account.currencyId) |
|
|
|
const currency = getCryptoCurrencyById(currencyId) |
|
|
|
|
|
|
|
const signedTransaction = await withDevice(deviceId)(async transport => |
|
|
|
signTransaction({ |
|
|
|
hwApp: new Btc(transport), |
|
|
|
currencyId: account.currencyId, |
|
|
|
currencyId, |
|
|
|
transaction: builded, |
|
|
|
sigHashType: parseInt(sigHashType, 16), |
|
|
|
supportsSegwit: !!currency.supportsSegwit, |
|
|
|
isSegwit: isSegwitAccount(account), |
|
|
|
isSegwit: isSegwitPath(freshAddressPath), |
|
|
|
hasTimestamp, |
|
|
|
}), |
|
|
|
) |
|
|
@ -221,7 +241,7 @@ export async function doSignAndBroadcast({ |
|
|
|
|
|
|
|
// NB we don't check isCancelled() because the broadcast is not cancellable now!
|
|
|
|
onOperationBroadcasted({ |
|
|
|
id: `${account.xpub}-${txHash}-OUT`, |
|
|
|
id: `${xpub}-${txHash}-OUT`, |
|
|
|
hash: txHash, |
|
|
|
type: 'OUT', |
|
|
|
value: BigNumber(transaction.amount) |
|
|
@ -230,9 +250,10 @@ export async function doSignAndBroadcast({ |
|
|
|
fee: fee.toString(), |
|
|
|
blockHash: null, |
|
|
|
blockHeight: null, |
|
|
|
senders: [account.freshAddress], |
|
|
|
// FIXME for senders and recipients, can we ask the libcore?
|
|
|
|
senders: [freshAddress], |
|
|
|
recipients: [transaction.recipient], |
|
|
|
accountId: account.id, |
|
|
|
accountId, |
|
|
|
date: new Date().toISOString(), |
|
|
|
}) |
|
|
|
} |
|
|
|