Browse Source

Merge pull request #347 from meriadec/btc-like-transaction

Btc like transaction & fix confirm address
master
Meriadec Pillet 7 years ago
committed by GitHub
parent
commit
6351e488a1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 141
      alix.js
  2. 4
      package.json
  3. 10
      src/bridge/EthereumJSBridge.js
  4. 14
      src/bridge/LibcoreBridge.js
  5. 2
      src/bridge/makeMockBridge.js
  6. 6
      src/bridge/types.js
  7. 22
      src/components/CurrentAddressForAccount.js
  8. 48
      src/components/DeviceCheckAddress.js
  9. 2
      src/components/DeviceSignTransaction.js
  10. 4
      src/components/modals/Receive/03-step-confirm-address.js
  11. 9
      src/components/modals/Receive/04-step-receive-funds.js
  12. 3
      src/helpers/getAddressForCurrency/index.js
  13. 3
      src/internals/accounts/index.js
  14. 62
      src/internals/accounts/scanAccountsOnDevice.js
  15. 71
      src/internals/accounts/signAndBroadcastTransaction/btc.js
  16. 1
      src/internals/index.js
  17. 4
      src/reducers/accounts.js
  18. 2
      src/renderer/runJob.js
  19. 12
      yarn.lock

141
alix.js

@ -1,141 +0,0 @@
/* eslint-disable no-console */
const CommNodeHid = require('@ledgerhq/hw-transport-node-hid').default
const Btc = require('@ledgerhq/hw-app-btc').default
const { CREATE } = process.env
const {
createWallet,
createAccount,
createAmount,
getCurrency,
getWallet,
syncAccount,
signTransaction,
} = require('@ledgerhq/ledger-core')
async function getOrCreateWallet(currencyId) {
try {
const wallet = await getWallet(currencyId)
return wallet
} catch (err) {
const currency = await getCurrency(currencyId)
const wallet = await createWallet(currencyId, currency)
return wallet
}
}
async function scanNextAccount(wallet, hwApp, accountIndex = 0) {
console.log(`creating an account with index ${accountIndex}`)
const account = await createAccount(wallet, hwApp)
console.log(`synchronizing account ${accountIndex}`)
await syncAccount(account)
console.log(`finished sync`)
const utxoCount = await account.asBitcoinLikeAccount().getUTXOCount()
console.log(`utxoCount = ${utxoCount}`)
}
async function scanAccountsOnDevice(props) {
try {
const { devicePath, currencyId } = props
console.log(`get or create wallet`)
const wallet = await getOrCreateWallet(currencyId)
console.log(`open device`)
const transport = await CommNodeHid.open(devicePath)
console.log(`create app`)
const hwApp = new Btc(transport)
console.log(`scan account`)
const accounts = await scanNextAccount(wallet, hwApp)
console.log(accounts)
return []
} catch (err) {
console.log(err)
}
}
waitForDevices(async device => {
// const accounts = await scanAccountsOnDevice({
// devicePath: device.path,
// currencyId: 'bitcoin_testnet',
// })
// console.log(accounts)
try {
console.log(`> Creating transport`)
const transport = await CommNodeHid.open(device.path)
// transport.setDebugMode(true)
console.log(`> Instanciate BTC app`)
const hwApp = new Btc(transport)
console.log(`> Get currency`)
const currency = await getCurrency('bitcoin_testnet')
console.log(`> Create wallet`)
const wallet = CREATE ? await createWallet('khalil', currency) : await getWallet('khalil')
console.log(`> Create account`)
const account = CREATE ? await createAccount(wallet, hwApp) : await wallet.getAccount(0)
console.log(`> Sync account`)
if (CREATE) {
await syncAccount(account)
}
console.log(`> Create transaction`)
const transaction = await createTransaction(wallet, account)
const signedTransaction = await signTransaction(hwApp, transaction)
await account.asBitcoinLikeAccount().broadcastRawTransaction(signedTransaction)
// console.log(signedTransaction);
process.exit(0)
// console.log(account.getIndex());
// console.log(account.isSynchronizing());
} catch (err) {
console.log(err.message)
process.exit(1)
}
})
function waitForDevices(onDevice) {
console.log(`> Waiting for device...`)
CommNodeHid.listen({
error: () => {},
complete: () => {},
next: async e => {
if (!e.device) {
return
}
if (e.type === 'add') {
console.log(`> Detected ${e.device.manufacturer} ${e.device.product}`)
onDevice(e.device)
}
if (e.type === 'remove') {
console.log(`removed ${JSON.stringify(e)}`)
}
},
})
}
async function createTransaction(wallet, account) {
const ADDRESS_TO_SEND = 'n2jdejywRogCunR2ozZAfXp1jMnfGpGXGR'
const bitcoinLikeAccount = account.asBitcoinLikeAccount()
const walletCurrency = wallet.getCurrency()
const amount = createAmount(walletCurrency, 10000)
console.log(`--------------------------------`)
console.log(amount.toLong())
console.log(`-----------------after `)
const fees = createAmount(walletCurrency, 1000)
const transactionBuilder = bitcoinLikeAccount.buildTransaction()
transactionBuilder.sendToAddress(amount, ADDRESS_TO_SEND)
// TODO: don't use hardcoded value for sequence (and first also maybe)
transactionBuilder.pickInputs(0, 0xffffff)
transactionBuilder.setFeesPerByte(fees)
return transactionBuilder.build()
}

4
package.json

@ -41,7 +41,7 @@
"@ledgerhq/hw-transport": "^4.12.0", "@ledgerhq/hw-transport": "^4.12.0",
"@ledgerhq/hw-transport-node-hid": "^4.12.0", "@ledgerhq/hw-transport-node-hid": "^4.12.0",
"@ledgerhq/ledger-core": "^1.0.1", "@ledgerhq/ledger-core": "^1.0.1",
"@ledgerhq/live-common": "^2.7.2", "@ledgerhq/live-common": "^2.7.5",
"axios": "^0.18.0", "axios": "^0.18.0",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
@ -84,7 +84,7 @@
"redux-thunk": "^2.2.0", "redux-thunk": "^2.2.0",
"reselect": "^3.0.1", "reselect": "^3.0.1",
"rxjs": "^6.2.0", "rxjs": "^6.2.0",
"rxjs-compat": "^6.2.0", "rxjs-compat": "^6.1.0",
"smooth-scrollbar": "^8.2.7", "smooth-scrollbar": "^8.2.7",
"source-map": "0.7.2", "source-map": "0.7.2",
"source-map-support": "^0.5.4", "source-map-support": "^0.5.4",

10
src/bridge/EthereumJSBridge.js

@ -97,12 +97,12 @@ const EthereumBridge: WalletBridge<Transaction> = {
const account: Account = { const account: Account = {
id: accountId, id: accountId,
xpub: '', xpub: '',
path, path, // FIXME we probably not want the address path in the account.path
walletPath: String(index), walletPath: String(index),
name: 'New Account', name: 'New Account',
isSegwit: false, isSegwit: false,
address, address,
addresses: [address], addresses: [{ str: address, path, }],
balance, balance,
blockHeight: currentBlock.height, blockHeight: currentBlock.height,
archived: true, archived: true,
@ -128,12 +128,12 @@ const EthereumBridge: WalletBridge<Transaction> = {
const account: Account = { const account: Account = {
id: accountId, id: accountId,
xpub: '', xpub: '',
path, path, // FIXME we probably not want the address path in the account.path
walletPath: String(index), walletPath: String(index),
name: address.slice(32), name: address.slice(32),
isSegwit: false, isSegwit: false,
address, address,
addresses: [address], addresses: [{ str: address, path, }],
balance, balance,
blockHeight: currentBlock.height, blockHeight: currentBlock.height,
archived: true, archived: true,
@ -263,7 +263,7 @@ const EthereumBridge: WalletBridge<Transaction> = {
getMaxAmount: (a, t) => Promise.resolve(a.balance - t.gasPrice), getMaxAmount: (a, t) => Promise.resolve(a.balance - t.gasPrice),
signAndBroadcast: async (a, t, deviceId) => { signAndBroadcast: async ({ account: a, transaction: t, deviceId }) => {
const api = apiForCurrency(a.currency) const api = apiForCurrency(a.currency)
const nonce = await api.getAccountNonce(a.address) const nonce = await api.getAccountNonce(a.address)

14
src/bridge/LibcoreBridge.js

@ -1,7 +1,8 @@
// @flow // @flow
import React from 'react' import React from 'react'
import { ipcRenderer } from 'electron' import { ipcRenderer } from 'electron'
import { decodeAccount } from 'reducers/accounts'
import { decodeAccount, encodeAccount } from 'reducers/accounts'
import runJob from 'renderer/runJob' import runJob from 'renderer/runJob'
import FeesBitcoinKind from 'components/FeesField/BitcoinKind' import FeesBitcoinKind from 'components/FeesField/BitcoinKind'
import AdvancedOptionsBitcoinKind from 'components/AdvancedOptions/BitcoinKind' import AdvancedOptionsBitcoinKind from 'components/AdvancedOptions/BitcoinKind'
@ -153,7 +154,16 @@ const LibcoreBridge: WalletBridge<Transaction> = {
getMaxAmount: (a, t) => Promise.resolve(a.balance - t.feePerByte), getMaxAmount: (a, t) => Promise.resolve(a.balance - t.feePerByte),
signAndBroadcast: () => Promise.reject(notImplemented), signAndBroadcast: ({ account, transaction, deviceId }) => {
const rawAccount = encodeAccount(account)
return runJob({
channel: 'accounts',
job: 'signAndBroadcastTransactionBTCLike',
successResponse: 'accounts.signAndBroadcastTransactionBTCLike.success',
errorResponse: 'accounts.signAndBroadcastTransactionBTCLike.fail',
data: { account: rawAccount, transaction, deviceId },
})
},
} }
export default LibcoreBridge export default LibcoreBridge

2
src/bridge/makeMockBridge.js

@ -146,7 +146,7 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
getMaxAmount, getMaxAmount,
signAndBroadcast: async (account, t) => { signAndBroadcast: async ({ account, transaction: t }) => {
const rng = new Prando() const rng = new Prando()
const op = genOperation(account, account.operations, account.currency, rng) const op = genOperation(account, account.operations, account.currency, rng)
op.amount = -t.amount op.amount = -t.amount

6
src/bridge/types.js

@ -98,5 +98,9 @@ export interface WalletBridge<Transaction> {
* NOTE: in future, when transaction balance is close to account.balance, we could wipe it all at this level... * NOTE: in future, when transaction balance is close to account.balance, we could wipe it all at this level...
* to implement that, we might want to have special logic `account.balance-transaction.amount < dust` but not sure where this should leave (i would say on UI side because we need to inform user visually). * to implement that, we might want to have special logic `account.balance-transaction.amount < dust` but not sure where this should leave (i would say on UI side because we need to inform user visually).
*/ */
signAndBroadcast(account: Account, transaction: Transaction, deviceId: DeviceId): Promise<string>; signAndBroadcast({
account: Account,
transaction: Transaction,
deviceId: DeviceId,
}): Promise<string>;
} }

22
src/components/CurrentAddressForAccount.js

@ -0,0 +1,22 @@
// @flow
import React from 'react'
import type { Account } from '@ledgerhq/live-common/lib/types'
import CurrentAddress from 'components/CurrentAddress'
type Props = {
account: Account,
}
export default function CurrentAddressForAccount(props: Props) {
const { account, ...p } = props
// TODO: handle other cryptos than BTC-like
let freshAddress = account.addresses[0]
if (!freshAddress) {
freshAddress = { str: '', path: '' }
}
return <CurrentAddress accountName={account.name} address={freshAddress.str} {...p} />
}

48
src/components/DeviceCheckAddress.js

@ -27,35 +27,47 @@ class CheckAddress extends PureComponent<Props, State> {
this.verifyAddress({ device, account }) this.verifyAddress({ device, account })
} }
componentDidUnmount() { componentWillUnmount() {
if (this.sub) this.sub.unsubscribe() this._isUnmounted = true
} }
sub: * _isUnmounted = false
verifyAddress = ({ device, account }: { device: Device, account: Account }) => { safeSetState = (...args: *) => {
this.sub = getAddress if (this._isUnmounted) {
return
}
this.setState(...args)
}
verifyAddress = async ({ device, account }: { device: Device, account: Account }) => {
try {
// TODO: this will work only for BTC-like accounts
const freshAddress = account.addresses[0]
if (!freshAddress) {
throw new Error('Account doesnt have fresh addresses')
}
const { address } = await getAddress
.send({ .send({
currencyId: account.currency.id, currencyId: account.currency.id,
devicePath: device.path, devicePath: device.path,
path: account.path, path: freshAddress.path,
segwit: account.isSegwit, segwit: account.isSegwit,
verify: true, verify: true,
}) })
.subscribe({ .toPromise()
next: () => {
this.setState({ if (address !== freshAddress.str) {
isVerified: true, throw new Error('Confirmed address is different')
}) }
this.safeSetState({ isVerified: true })
this.props.onCheck(true) this.props.onCheck(true)
}, } catch (err) {
error: () => { this.safeSetState({ isVerified: false })
this.setState({
isVerified: false,
})
this.props.onCheck(false) this.props.onCheck(false)
}, }
})
} }
render() { render() {

2
src/components/DeviceSignTransaction.js

@ -34,7 +34,7 @@ class DeviceSignTransaction extends PureComponent<Props, State> {
sign = async () => { sign = async () => {
const { device, account, transaction, bridge, onSuccess } = this.props const { device, account, transaction, bridge, onSuccess } = this.props
try { try {
const txid = await bridge.signAndBroadcast(account, transaction, device.path) const txid = await bridge.signAndBroadcast({ account, transaction, deviceId: device.path })
onSuccess(txid) onSuccess(txid)
} catch (error) { } catch (error) {
this.setState({ error }) this.setState({ error })

4
src/components/modals/Receive/03-step-confirm-address.js

@ -7,7 +7,7 @@ import type { Account } from '@ledgerhq/live-common/lib/types'
import type { Device, T } from 'types/common' import type { Device, T } from 'types/common'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import CurrentAddress from 'components/CurrentAddress' import CurrentAddressForAccount from 'components/CurrentAddressForAccount'
import DeviceConfirm from 'components/DeviceConfirm' import DeviceConfirm from 'components/DeviceConfirm'
import DeviceCheckAddress from 'components/DeviceCheckAddress' import DeviceCheckAddress from 'components/DeviceCheckAddress'
@ -50,7 +50,7 @@ export default (props: Props) => (
<Fragment> <Fragment>
<Title>{props.t('receive:steps.confirmAddress.action')}</Title> <Title>{props.t('receive:steps.confirmAddress.action')}</Title>
<Text>{props.t('receive:steps.confirmAddress.text')}</Text> <Text>{props.t('receive:steps.confirmAddress.text')}</Text>
{props.account && <CurrentAddress address={props.account.address} />} {props.account && <CurrentAddressForAccount account={props.account} />}
{props.device && {props.device &&
props.account && ( props.account && (
<Box mb={2} mt={-1}> <Box mb={2} mt={-1}>

9
src/components/modals/Receive/04-step-receive-funds.js

@ -6,7 +6,7 @@ import type { Account } from '@ledgerhq/live-common/lib/types'
import type { T } from 'types/common' import type { T } from 'types/common'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import CurrentAddress from 'components/CurrentAddress' import CurrentAddressForAccount from 'components/CurrentAddressForAccount'
import Label from 'components/base/Label' import Label from 'components/base/Label'
import RequestAmount from 'components/RequestAmount' import RequestAmount from 'components/RequestAmount'
@ -30,9 +30,9 @@ export default (props: Props) => (
withMax={false} withMax={false}
/> />
</Box> </Box>
<CurrentAddress {props.account && (
accountName={props.account && props.account.name} <CurrentAddressForAccount
address={props.account && props.account.address} account={props.account}
addressVerified={props.addressVerified} addressVerified={props.addressVerified}
amount={props.amount} amount={props.amount}
onVerify={props.onVerify} onVerify={props.onVerify}
@ -41,5 +41,6 @@ export default (props: Props) => (
withQRCode withQRCode
withVerify={props.addressVerified === false} withVerify={props.addressVerified === false}
/> />
)}
</Box> </Box>
) )

3
src/helpers/getAddressForCurrency/index.js

@ -26,6 +26,7 @@ const all = {
ethereum_classic_testnet: ethereum, ethereum_classic_testnet: ethereum,
} }
const getAddressForCurrency: Module = (currencyId: string) => all[currencyId] || fallback(currencyId) const getAddressForCurrency: Module = (currencyId: string) =>
all[currencyId] || fallback(currencyId)
export default getAddressForCurrency export default getAddressForCurrency

3
src/internals/accounts/index.js

@ -3,11 +3,13 @@
import type { IPCSend } from 'types/electron' import type { IPCSend } from 'types/electron'
import scanAccountsOnDevice from './scanAccountsOnDevice' import scanAccountsOnDevice from './scanAccountsOnDevice'
import signAndBroadcastTransactionBTCLike from './signAndBroadcastTransaction/btc'
import sync from './sync' import sync from './sync'
export default { export default {
sync, sync,
signAndBroadcastTransactionBTCLike,
scan: async ( scan: async (
send: IPCSend, send: IPCSend,
{ {
@ -29,7 +31,6 @@ export default {
}) })
send('accounts.scanAccountsOnDevice.success', accounts) send('accounts.scanAccountsOnDevice.success', accounts)
} catch (err) { } catch (err) {
console.log(err)
send('accounts.scanAccountsOnDevice.fail', formatErr(err)) send('accounts.scanAccountsOnDevice.fail', formatErr(err))
} }
}, },

62
src/internals/accounts/scanAccountsOnDevice.js

@ -46,19 +46,39 @@ export default async function scanAccountsOnDevice(props: Props): Promise<Accoun
return accounts return accounts
} }
async function scanAccountsOnDeviceBySegwit({ export async function getWalletIdentifier({
hwApp, hwApp,
isSegwit,
currencyId, currencyId,
onAccountScanned,
devicePath, devicePath,
isSegwit, }: {
}) { hwApp: Object,
// compute wallet identifier isSegwit: boolean,
currencyId: string,
devicePath: string,
}): Promise<string> {
const isVerify = false const isVerify = false
const deviceIdentifiers = await hwApp.getWalletPublicKey(devicePath, isVerify, isSegwit) const deviceIdentifiers = await hwApp.getWalletPublicKey(devicePath, isVerify, isSegwit)
const { publicKey } = deviceIdentifiers const { publicKey } = deviceIdentifiers
const WALLET_IDENTIFIER = `${publicKey}__${currencyId}${isSegwit ? '_segwit' : ''}` const WALLET_IDENTIFIER = `${publicKey}__${currencyId}${isSegwit ? '_segwit' : ''}`
return WALLET_IDENTIFIER
}
async function scanAccountsOnDeviceBySegwit({
hwApp,
currencyId,
onAccountScanned,
devicePath,
isSegwit,
}: {
hwApp: Object,
currencyId: string,
onAccountScanned: AccountRaw => void,
devicePath: string,
isSegwit: boolean,
}): Promise<AccountRaw[]> {
// compute wallet identifier
const WALLET_IDENTIFIER = await getWalletIdentifier({ hwApp, isSegwit, currencyId, devicePath })
// retrieve or create the wallet // retrieve or create the wallet
const wallet = await getOrCreateWallet(WALLET_IDENTIFIER, currencyId, isSegwit) const wallet = await getOrCreateWallet(WALLET_IDENTIFIER, currencyId, isSegwit)
@ -80,7 +100,17 @@ async function scanAccountsOnDeviceBySegwit({
return accounts return accounts
} }
async function scanNextAccount(props) { async function scanNextAccount(props: {
// $FlowFixMe
wallet: NJSWallet,
hwApp: Object,
currencyId: string,
accountsCount: number,
accountIndex: number,
accounts: AccountRaw[],
onAccountScanned: AccountRaw => void,
isSegwit: boolean,
}): Promise<AccountRaw[]> {
const { const {
wallet, wallet,
hwApp, hwApp,
@ -136,7 +166,11 @@ async function scanNextAccount(props) {
return scanNextAccount({ ...props, accountIndex: accountIndex + 1 }) return scanNextAccount({ ...props, accountIndex: accountIndex + 1 })
} }
async function getOrCreateWallet(WALLET_IDENTIFIER, currencyId, isSegwit) { async function getOrCreateWallet(
WALLET_IDENTIFIER: string,
currencyId: string,
isSegwit: boolean,
): NJSWallet {
// TODO: investigate why importing it on file scope causes trouble // TODO: investigate why importing it on file scope causes trouble
const core = require('init-ledger-core')() const core = require('init-ledger-core')()
try { try {
@ -176,7 +210,7 @@ async function buildAccountRaw({
hwApp: Object, hwApp: Object,
// $FlowFixMe // $FlowFixMe
ops: NJSOperation[], ops: NJSOperation[],
}) { }): Promise<AccountRaw> {
const balanceByDay = ops.length const balanceByDay = ops.length
? await getBalanceByDaySinceOperation({ ? await getBalanceByDaySinceOperation({
njsAccount, njsAccount,
@ -204,10 +238,10 @@ async function buildAccountRaw({
// get a bunch of fresh addresses // get a bunch of fresh addresses
const rawAddresses = await njsAccount.getFreshPublicAddresses() const rawAddresses = await njsAccount.getFreshPublicAddresses()
// TODO: waiting for libcore
const addresses = rawAddresses.map((strAddr, i) => ({ const addresses = rawAddresses.map(njsAddress => ({
str: strAddr, str: njsAddress.toString(),
path: `${accountPath}/${i}'`, path: `${accountPath}/${njsAddress.getDerivationPath()}`,
})) }))
const operations = ops.map(op => buildOperationRaw({ core, op, xpub })) const operations = ops.map(op => buildOperationRaw({ core, op, xpub }))
@ -295,7 +329,7 @@ async function getBalanceByDaySinceOperation({
return res return res
} }
function areSameDay(date1, date2) { function areSameDay(date1: Date, date2: Date): boolean {
return ( return (
date1.getFullYear() === date2.getFullYear() && date1.getFullYear() === date2.getFullYear() &&
date1.getMonth() === date2.getMonth() && date1.getMonth() === date2.getMonth() &&

71
src/internals/accounts/signAndBroadcastTransaction/btc.js

@ -0,0 +1,71 @@
// @flow
import Btc from '@ledgerhq/hw-app-btc'
import CommNodeHid from '@ledgerhq/hw-transport-node-hid'
import type { AccountRaw } from '@ledgerhq/live-common/lib/types'
import type Transport from '@ledgerhq/hw-transport'
import type { IPCSend } from 'types/electron'
import { getWalletIdentifier } from '../scanAccountsOnDevice'
type BitcoinLikeTransaction = {
amount: number,
feePerByte: number,
recipient: string,
}
export default async function signAndBroadcastTransactionBTCLike(
send: IPCSend,
{
account,
transaction,
deviceId, // which is in fact `devicePath`
}: {
account: AccountRaw,
transaction: BitcoinLikeTransaction,
deviceId: string,
},
) {
try {
// TODO: investigate why importing it on file scope causes trouble
const core = require('init-ledger-core')()
// instanciate app on device
const transport: Transport<*> = await CommNodeHid.open(deviceId)
const hwApp = new Btc(transport)
const WALLET_IDENTIFIER = await getWalletIdentifier({
hwApp,
isSegwit: account.isSegwit,
currencyId: account.currencyId,
devicePath: deviceId,
})
const njsWallet = await core.getWallet(WALLET_IDENTIFIER)
const njsAccount = await njsWallet.getAccount(account.index)
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()
const signedTransaction = await core.signTransaction(hwApp, builded)
const txHash = await njsAccount
.asBitcoinLikeAccount()
.broadcastRawTransaction(signedTransaction)
send('accounts.signAndBroadcastTransactionBTCLike.success', txHash)
} catch (err) {
send('accounts.signAndBroadcastTransactionBTCLike.fail', err)
}
}

1
src/internals/index.js

@ -24,7 +24,6 @@ if (handlers.default) {
} }
process.on('message', payload => { process.on('message', payload => {
console.log(payload)
if (payload.data && payload.data.requestId) { if (payload.data && payload.data.requestId) {
const { data, requestId, id } = payload.data const { data, requestId, id } = payload.data
// this is the new type of "command" payload! // this is the new type of "command" payload!

4
src/reducers/accounts.js

@ -119,6 +119,10 @@ export function decodeAccount(account: AccountRaw): Account {
}) })
} }
export function encodeAccount(account: Account): AccountRaw {
return accountModel.encode(account).data
}
// Yeah. `any` should be `AccountRaw[]` but it can also be a map // Yeah. `any` should be `AccountRaw[]` but it can also be a map
// of wrapped accounts. And as flow is apparently incapable of doing // of wrapped accounts. And as flow is apparently incapable of doing
// such a simple thing, let's put any, right? I don't care. // such a simple thing, let's put any, right? I don't care.

2
src/renderer/runJob.js

@ -14,7 +14,7 @@ export default function runJob({
successResponse: string, successResponse: string,
errorResponse: string, errorResponse: string,
data?: any, data?: any,
}): Promise<void> { }): Promise<any> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
ipcRenderer.send(channel, { type: job, data }) ipcRenderer.send(channel, { type: job, data })
ipcRenderer.on('msg', handler) ipcRenderer.on('msg', handler)

12
yarn.lock

@ -1473,9 +1473,9 @@
npm "^5.7.1" npm "^5.7.1"
prebuild-install "^2.2.2" prebuild-install "^2.2.2"
"@ledgerhq/live-common@^2.7.2": "@ledgerhq/live-common@^2.7.5":
version "2.7.2" version "2.7.5"
resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-2.7.2.tgz#abfa71428c186220006d35baca44261a1c3ef9ed" resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-2.7.5.tgz#5434bf2e708aaca471be4ca823e613cf27ba700c"
dependencies: dependencies:
axios "^0.18.0" axios "^0.18.0"
invariant "^2.2.2" invariant "^2.2.2"
@ -12051,9 +12051,9 @@ rx@2.3.24:
version "2.3.24" version "2.3.24"
resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7" resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7"
rxjs-compat@^6.2.0: rxjs-compat@^6.1.0:
version "6.2.0" version "6.1.0"
resolved "https://registry.yarnpkg.com/rxjs-compat/-/rxjs-compat-6.2.0.tgz#2eb49cc6ac20d0d7057c6887d1895beaab0966f9" resolved "https://registry.yarnpkg.com/rxjs-compat/-/rxjs-compat-6.1.0.tgz#935059623ee4c167728c9dd03ee6e4468cc5b583"
rxjs@^5.1.1, rxjs@^5.4.2, rxjs@^5.5.2: rxjs@^5.1.1, rxjs@^5.4.2, rxjs@^5.5.2:
version "5.5.10" version "5.5.10"

Loading…
Cancel
Save