diff --git a/alix.js b/alix.js deleted file mode 100644 index eab6144c..00000000 --- a/alix.js +++ /dev/null @@ -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() -} diff --git a/electron-builder.yml b/electron-builder.yml index e1fa6ca0..8549bcc6 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -83,6 +83,5 @@ files: - "!node_modules/react-dom/umd{,/**/*}" - "!node_modules/react-qr-reader/src{,/**/*}" - "!node_modules/react/umd{,/**/*}" - - "!node_modules/rxjs{,/**/*}" - "!node_modules/source-map/dist{,/**/*}" - "!node_modules/styled-components/src{,/**/*}" diff --git a/package.json b/package.json index b6ec1bed..ebaebba7 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "test": "jest", "flow": "flow", "lint": "eslint src webpack .storybook", + "ci": "yarn lint && yarn flow && yarn prettier && yarn test", "postinstall": "bash ./scripts/postinstall.sh", "prettier": "prettier --write \"{src,webpack,.storybook}/**/*.js\"", "publish-storybook": "bash ./scripts/publish-storybook.sh", @@ -40,7 +41,7 @@ "@ledgerhq/hw-transport": "^4.12.0", "@ledgerhq/hw-transport-node-hid": "^4.12.0", "@ledgerhq/ledger-core": "^1.0.1", - "@ledgerhq/live-common": "^2.7.2", + "@ledgerhq/live-common": "^2.7.5", "axios": "^0.18.0", "babel-runtime": "^6.26.0", "bcryptjs": "^2.4.3", @@ -83,7 +84,7 @@ "redux-thunk": "^2.2.0", "reselect": "^3.0.1", "rxjs": "^6.2.0", - "rxjs-compat": "^6.2.0", + "rxjs-compat": "^6.1.0", "smooth-scrollbar": "^8.2.7", "source-map": "0.7.2", "source-map-support": "^0.5.4", diff --git a/src/bridge/EthereumJSBridge.js b/src/bridge/EthereumJSBridge.js index 163b7b8c..68c16971 100644 --- a/src/bridge/EthereumJSBridge.js +++ b/src/bridge/EthereumJSBridge.js @@ -99,12 +99,12 @@ const EthereumBridge: WalletBridge = { const account: Account = { id: accountId, xpub: '', - path, + path, // FIXME we probably not want the address path in the account.path walletPath: String(index), name: 'New Account', isSegwit: false, address, - addresses: [address], + addresses: [{ str: address, path, }], balance, blockHeight: currentBlock.height, archived: true, @@ -130,12 +130,12 @@ const EthereumBridge: WalletBridge = { const account: Account = { id: accountId, xpub: '', - path, + path, // FIXME we probably not want the address path in the account.path walletPath: String(index), name: address.slice(32), isSegwit: false, address, - addresses: [address], + addresses: [{ str: address, path, }], balance, blockHeight: currentBlock.height, archived: true, @@ -266,7 +266,7 @@ const EthereumBridge: WalletBridge = { 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 nonce = await api.getAccountNonce(a.address) diff --git a/src/bridge/LibcoreBridge.js b/src/bridge/LibcoreBridge.js index eb4864fe..9b9776cd 100644 --- a/src/bridge/LibcoreBridge.js +++ b/src/bridge/LibcoreBridge.js @@ -1,7 +1,8 @@ // @flow import React from 'react' import { ipcRenderer } from 'electron' -import { decodeAccount } from 'reducers/accounts' + +import { decodeAccount, encodeAccount } from 'reducers/accounts' import runJob from 'renderer/runJob' import FeesBitcoinKind from 'components/FeesField/BitcoinKind' import AdvancedOptionsBitcoinKind from 'components/AdvancedOptions/BitcoinKind' @@ -153,7 +154,16 @@ const LibcoreBridge: WalletBridge = { 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 diff --git a/src/bridge/makeMockBridge.js b/src/bridge/makeMockBridge.js index 1bc2eef9..21032f3d 100644 --- a/src/bridge/makeMockBridge.js +++ b/src/bridge/makeMockBridge.js @@ -146,7 +146,7 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> { getMaxAmount, - signAndBroadcast: async (account, t) => { + signAndBroadcast: async ({ account, transaction: t }) => { const rng = new Prando() const op = genOperation(account, account.operations, account.currency, rng) op.amount = -t.amount diff --git a/src/bridge/types.js b/src/bridge/types.js index 716ba35d..d85d3fe0 100644 --- a/src/bridge/types.js +++ b/src/bridge/types.js @@ -98,5 +98,9 @@ export interface WalletBridge { * 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). */ - signAndBroadcast(account: Account, transaction: Transaction, deviceId: DeviceId): Promise; + signAndBroadcast({ + account: Account, + transaction: Transaction, + deviceId: DeviceId, + }): Promise; } diff --git a/src/components/CurrentAddressForAccount.js b/src/components/CurrentAddressForAccount.js new file mode 100644 index 00000000..6bbd6547 --- /dev/null +++ b/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 +} diff --git a/src/components/DeviceCheckAddress.js b/src/components/DeviceCheckAddress.js index b94dadf2..0ee2a324 100644 --- a/src/components/DeviceCheckAddress.js +++ b/src/components/DeviceCheckAddress.js @@ -27,35 +27,47 @@ class CheckAddress extends PureComponent { this.verifyAddress({ device, account }) } - componentDidUnmount() { - if (this.sub) this.sub.unsubscribe() + componentWillUnmount() { + this._isUnmounted = true } - sub: * - - verifyAddress = ({ device, account }: { device: Device, account: Account }) => { - this.sub = getAddress - .send({ - currencyId: account.currency.id, - devicePath: device.path, - path: account.path, - segwit: account.isSegwit, - verify: true, - }) - .subscribe({ - next: () => { - this.setState({ - isVerified: true, - }) - this.props.onCheck(true) - }, - error: () => { - this.setState({ - isVerified: false, - }) - this.props.onCheck(false) - }, - }) + _isUnmounted = false + + safeSetState = (...args: *) => { + 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({ + currencyId: account.currency.id, + devicePath: device.path, + path: freshAddress.path, + segwit: account.isSegwit, + verify: true, + }) + .toPromise() + + if (address !== freshAddress.str) { + throw new Error('Confirmed address is different') + } + + this.safeSetState({ isVerified: true }) + this.props.onCheck(true) + } catch (err) { + this.safeSetState({ isVerified: false }) + this.props.onCheck(false) + } } render() { diff --git a/src/components/DeviceConnect/stories.js b/src/components/DeviceConnect/stories.js index 4b729e3d..1032e803 100644 --- a/src/components/DeviceConnect/stories.js +++ b/src/components/DeviceConnect/stories.js @@ -4,9 +4,16 @@ import React from 'react' import { storiesOf } from '@storybook/react' import { boolean, select, text } from '@storybook/addon-knobs' import { action } from '@storybook/addon-actions' +import { + getCryptoCurrencyById, + listCryptoCurrencies, +} from '@ledgerhq/live-common/lib/helpers/currencies' + +import type { Currency } from '@ledgerhq/live-common/lib/types' import DeviceConnect from 'components/DeviceConnect' +const currencies = listCryptoCurrencies().map(c => c.id) const stories = storiesOf('Components', module) const devices = [ @@ -34,12 +41,27 @@ const devices = [ ] stories.add('DeviceConnect', () => ( - + + {({ currency }) => ( + + )} + )) + +function Wrapper({ + currencyId, + children, +}: { + currencyId: string, + children: (props: { currency: Currency }) => any, +}) { + const currency = getCryptoCurrencyById(currencyId) + return children({ currency }) +} diff --git a/src/components/DeviceSignTransaction.js b/src/components/DeviceSignTransaction.js index 471c3ab4..ff9c3865 100644 --- a/src/components/DeviceSignTransaction.js +++ b/src/components/DeviceSignTransaction.js @@ -34,7 +34,7 @@ class DeviceSignTransaction extends PureComponent { sign = async () => { const { device, account, transaction, bridge, onSuccess } = this.props try { - const txid = await bridge.signAndBroadcast(account, transaction, device.path) + const txid = await bridge.signAndBroadcast({ account, transaction, deviceId: device.path }) onSuccess(txid) } catch (error) { this.setState({ error }) diff --git a/src/components/SelectAccount/index.js b/src/components/SelectAccount/index.js index f3fd2925..5ab4067a 100644 --- a/src/components/SelectAccount/index.js +++ b/src/components/SelectAccount/index.js @@ -22,8 +22,13 @@ const mapStateToProps = state => ({ }) const renderItem = a => { - const Icon = getCryptoCurrencyIcon(a) + const Icon = getCryptoCurrencyIcon(a.currency) const { color } = a.currency + + // FIXME: we need a non-hacky way to handle text ellipsis + const nameOuterStyle = { width: 0 } + const nameInnerStyle = { overflow: 'hidden', textOverflow: 'ellipsis' } + return ( {Icon && ( @@ -31,8 +36,8 @@ const renderItem = a => { )} - - + + {a.name} diff --git a/src/components/modals/Receive/03-step-confirm-address.js b/src/components/modals/Receive/03-step-confirm-address.js index 2f205e1b..46cf076f 100644 --- a/src/components/modals/Receive/03-step-confirm-address.js +++ b/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 Box from 'components/base/Box' -import CurrentAddress from 'components/CurrentAddress' +import CurrentAddressForAccount from 'components/CurrentAddressForAccount' import DeviceConfirm from 'components/DeviceConfirm' import DeviceCheckAddress from 'components/DeviceCheckAddress' @@ -50,7 +50,7 @@ export default (props: Props) => ( {props.t('receive:steps.confirmAddress.action')} {props.t('receive:steps.confirmAddress.text')} - {props.account && } + {props.account && } {props.device && props.account && ( diff --git a/src/components/modals/Receive/04-step-receive-funds.js b/src/components/modals/Receive/04-step-receive-funds.js index a913b8a7..98096f7f 100644 --- a/src/components/modals/Receive/04-step-receive-funds.js +++ b/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 Box from 'components/base/Box' -import CurrentAddress from 'components/CurrentAddress' +import CurrentAddressForAccount from 'components/CurrentAddressForAccount' import Label from 'components/base/Label' import RequestAmount from 'components/RequestAmount' @@ -30,16 +30,17 @@ export default (props: Props) => ( withMax={false} /> - + {props.account && ( + + )} ) diff --git a/src/helpers/getAddressForCurrency/index.js b/src/helpers/getAddressForCurrency/index.js index 329657b5..b96813e3 100644 --- a/src/helpers/getAddressForCurrency/index.js +++ b/src/helpers/getAddressForCurrency/index.js @@ -26,6 +26,7 @@ const all = { 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 diff --git a/src/internals/accounts/index.js b/src/internals/accounts/index.js index 18c02cfe..6a18e8e8 100644 --- a/src/internals/accounts/index.js +++ b/src/internals/accounts/index.js @@ -3,11 +3,13 @@ import type { IPCSend } from 'types/electron' import scanAccountsOnDevice from './scanAccountsOnDevice' +import signAndBroadcastTransactionBTCLike from './signAndBroadcastTransaction/btc' import sync from './sync' export default { sync, + signAndBroadcastTransactionBTCLike, scan: async ( send: IPCSend, { @@ -29,7 +31,6 @@ export default { }) send('accounts.scanAccountsOnDevice.success', accounts) } catch (err) { - console.log(err) send('accounts.scanAccountsOnDevice.fail', formatErr(err)) } }, diff --git a/src/internals/accounts/scanAccountsOnDevice.js b/src/internals/accounts/scanAccountsOnDevice.js index f8ba2daf..3dbbed7b 100644 --- a/src/internals/accounts/scanAccountsOnDevice.js +++ b/src/internals/accounts/scanAccountsOnDevice.js @@ -46,19 +46,39 @@ export default async function scanAccountsOnDevice(props: Props): 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 +} + +async function scanAccountsOnDeviceBySegwit({ + hwApp, + currencyId, + onAccountScanned, + devicePath, + isSegwit, +}: { + hwApp: Object, + currencyId: string, + onAccountScanned: AccountRaw => void, + devicePath: string, + isSegwit: boolean, +}): Promise { + // compute wallet identifier + const WALLET_IDENTIFIER = await getWalletIdentifier({ hwApp, isSegwit, currencyId, devicePath }) // retrieve or create the wallet const wallet = await getOrCreateWallet(WALLET_IDENTIFIER, currencyId, isSegwit) @@ -80,7 +100,17 @@ async function scanAccountsOnDeviceBySegwit({ 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 { const { wallet, hwApp, @@ -136,7 +166,11 @@ async function scanNextAccount(props) { 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 const core = require('init-ledger-core')() try { @@ -176,7 +210,7 @@ async function buildAccountRaw({ hwApp: Object, // $FlowFixMe ops: NJSOperation[], -}) { +}): Promise { const balanceByDay = ops.length ? await getBalanceByDaySinceOperation({ njsAccount, @@ -204,10 +238,10 @@ async function buildAccountRaw({ // get a bunch of fresh addresses const rawAddresses = await njsAccount.getFreshPublicAddresses() - // TODO: waiting for libcore - const addresses = rawAddresses.map((strAddr, i) => ({ - str: strAddr, - path: `${accountPath}/${i}'`, + + const addresses = rawAddresses.map(njsAddress => ({ + str: njsAddress.toString(), + path: `${accountPath}/${njsAddress.getDerivationPath()}`, })) const operations = ops.map(op => buildOperationRaw({ core, op, xpub })) @@ -295,7 +329,7 @@ async function getBalanceByDaySinceOperation({ return res } -function areSameDay(date1, date2) { +function areSameDay(date1: Date, date2: Date): boolean { return ( date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && diff --git a/src/internals/accounts/signAndBroadcastTransaction/btc.js b/src/internals/accounts/signAndBroadcastTransaction/btc.js new file mode 100644 index 00000000..7afae5c6 --- /dev/null +++ b/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) + } +} diff --git a/src/internals/index.js b/src/internals/index.js index 88a8ca08..4cc59b34 100644 --- a/src/internals/index.js +++ b/src/internals/index.js @@ -24,7 +24,6 @@ if (handlers.default) { } process.on('message', payload => { - console.log(payload) if (payload.data && payload.data.requestId) { const { data, requestId, id } = payload.data // this is the new type of "command" payload! diff --git a/src/reducers/accounts.js b/src/reducers/accounts.js index 6ecb4009..40847073 100644 --- a/src/reducers/accounts.js +++ b/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 // of wrapped accounts. And as flow is apparently incapable of doing // such a simple thing, let's put any, right? I don't care. diff --git a/src/renderer/runJob.js b/src/renderer/runJob.js index fa136b48..b2fc8e64 100644 --- a/src/renderer/runJob.js +++ b/src/renderer/runJob.js @@ -14,7 +14,7 @@ export default function runJob({ successResponse: string, errorResponse: string, data?: any, -}): Promise { +}): Promise { return new Promise((resolve, reject) => { ipcRenderer.send(channel, { type: job, data }) ipcRenderer.on('msg', handler) diff --git a/yarn.lock b/yarn.lock index cc07b02a..f3e7fa88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1473,9 +1473,9 @@ npm "^5.7.1" prebuild-install "^2.2.2" -"@ledgerhq/live-common@^2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-2.7.2.tgz#abfa71428c186220006d35baca44261a1c3ef9ed" +"@ledgerhq/live-common@^2.7.5": + version "2.7.5" + resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-2.7.5.tgz#5434bf2e708aaca471be4ca823e613cf27ba700c" dependencies: axios "^0.18.0" invariant "^2.2.2" @@ -12051,9 +12051,9 @@ rx@2.3.24: version "2.3.24" resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7" -rxjs-compat@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/rxjs-compat/-/rxjs-compat-6.2.0.tgz#2eb49cc6ac20d0d7057c6887d1895beaab0966f9" +rxjs-compat@^6.1.0: + version "6.1.0" + 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: version "5.5.10"