Browse Source

Send correct info through action -> command -> libcore -> redux

master
meriadec 7 years ago
parent
commit
44531e6ba9
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 14
      src/bridge/LibcoreBridge.js
  2. 2
      src/commands/libcoreSignAndBroadcast.js
  3. 5
      src/commands/libcoreSyncAccount.js
  4. 10
      src/components/SideBar/Item.js
  5. 11
      src/components/TopBar/ActivityIndicator.js
  6. 16
      src/helpers/accountId.js
  7. 62
      src/helpers/libcore.js
  8. 19
      src/helpers/withLibcore.js

14
src/bridge/LibcoreBridge.js

@ -51,6 +51,11 @@ const LibcoreBridge: WalletBridge<Transaction> = {
},
synchronize(account, { next, complete, error }) {
// FIXME TODO:
// - when you implement addPendingOperation you also here need to:
// - if there were pendingOperations that are now in operations, remove them as well.
// - if there are pendingOperations that is older than a threshold (that depends on blockchain speed typically)
// then we probably should trash them out? it's a complex question for UI
;(async () => {
try {
const rawAccount = encodeAccount(account)
@ -68,15 +73,6 @@ const LibcoreBridge: WalletBridge<Transaction> = {
error(e)
}
})()
// FIXME TODO: use next(), to actually emit account updates.....
// - need to sync the balance
// - need to sync block height & block hash
// - need to sync operations.
// - once all that, need to set lastSyncDate to new Date()
// - when you implement addPendingOperation you also here need to:
// - if there were pendingOperations that are now in operations, remove them as well.
// - if there are pendingOperations that is older than a threshold (that depends on blockchain speed typically)
// then we probably should trash them out? it's a complex question for UI
return {
unsubscribe() {
console.warn('LibcoreBridge: unsub sync not implemented')

2
src/commands/libcoreSignAndBroadcast.js

@ -63,7 +63,7 @@ const cmd: Command<Input, Result> = createCommand(
const signedTransaction = await core.signTransaction({
hwApp,
transaction: builded,
sigHashType: `0x${sigHashType}`,
sigHashType: parseInt(sigHashType, 16).toString(),
supportsSegwit: !!currency.supportsSegwit,
isSegwit: account.isSegwit,
})

5
src/commands/libcoreSyncAccount.js

@ -8,14 +8,15 @@ import { syncAccount } from 'helpers/libcore'
import withLibcore from 'helpers/withLibcore'
type Input = {
core: Object,
rawAccount: AccountRaw,
}
type Result = AccountRaw
const cmd: Command<Input, Result> = createCommand('libcoreSyncAccount', ({ rawAccount }) =>
fromPromise(withLibcore(core => syncAccount({ rawAccount, core }))),
fromPromise(
withLibcore((core, njsWalletPool) => syncAccount({ rawAccount, core, njsWalletPool })),
),
)
export default cmd

10
src/components/SideBar/Item.js

@ -3,7 +3,7 @@
import React from 'react'
import styled from 'styled-components'
import { compose } from 'redux'
import { matchPath, withRouter } from 'react-router'
import { withRouter } from 'react-router'
import { push } from 'react-router-redux'
import { connect } from 'react-redux'
@ -91,13 +91,7 @@ function Item({
highlight,
}: Props) {
const { pathname } = location
const isActive = linkTo
? linkTo === '/'
? linkTo === pathname
: matchPath(pathname, {
path: linkTo,
})
: false
const isActive = linkTo === pathname
return (
<Container
big={big}

11
src/components/TopBar/ActivityIndicator.js

@ -18,12 +18,11 @@ const Activity = styled.div`
? p.theme.colors.alertRed
: p.theme.colors.positiveGreen};
border-radius: 50%;
bottom: 20px;
height: 4px;
bottom: 23px;
position: absolute;
right: 8px;
width: 4px;
cursor: pointer;
left: -5px;
width: 12px;
height: 12px;
`
const mapStateToProps = createStructuredSelector({ globalSyncState: globalSyncStateSelector })
@ -32,7 +31,7 @@ class ActivityIndicatorUI extends Component<*> {
render() {
const { pending, error, onClick } = this.props
return (
<ItemContainer relative onClick={onClick}>
<ItemContainer cursor="pointer" relative onClick={onClick}>
<IconActivity size={16} />
<Activity pending={pending} error={error} />
</ItemContainer>

16
src/helpers/accountId.js

@ -0,0 +1,16 @@
// @flow
type Params = {
type: string,
xpub: string,
walletName: string,
}
export function encode({ type, xpub, walletName }: Params) {
return `${type}:${xpub}:${walletName}`
}
export function decode(accountId: string) {
const [type, xpub, walletName] = accountId.split(':')
return { type, xpub, walletName }
}

62
src/helpers/libcore.js

@ -7,6 +7,8 @@ import { getCryptoCurrencyById } from '@ledgerhq/live-common/lib/helpers/currenc
import type { AccountRaw, OperationRaw, OperationType } from '@ledgerhq/live-common/lib/types'
import type { NJSAccount, NJSOperation } from '@ledgerhq/ledger-core/src/ledgercore_doc'
import * as accountId from 'helpers/accountId'
type Props = {
core: Object,
devicePath: string,
@ -80,6 +82,7 @@ async function scanAccountsOnDeviceBySegwit({
isSegwit,
showNewAccount,
}: {
core: Object,
hwApp: Object,
currencyId: string,
onAccountScanned: AccountRaw => void,
@ -138,8 +141,6 @@ async function scanNextAccount(props: {
showNewAccount,
} = props
console.log(`>> Scanning account ${accountIndex} - isSegwit: ${isSegwit.toString()}`) // eslint-disable-line no-console
// create account only if account has not been scanned yet
// if it has already been created, we just need to get it, and sync it
const hasBeenScanned = accountIndex < accountsCount
@ -220,7 +221,6 @@ async function buildAccountRaw({
currencyId: string,
accountIndex: number,
core: Object,
hwApp: Object,
// $FlowFixMe
ops: NJSOperation[],
}): Promise<AccountRaw> {
@ -260,7 +260,7 @@ async function buildAccountRaw({
}
const rawAccount: AccountRaw = {
id: xpub, // FIXME for account id you might want to prepend the crypto currency id to this because it's not gonna be unique.
id: accountId.encode({ type: 'libcore', xpub, walletName: wallet.getName() }),
xpub,
path: walletPath,
name,
@ -319,26 +319,38 @@ function buildOperationRaw({
}
}
export async function syncAccount({ rawAccount }: { rawAccount: AccountRaw }) {
// AWWWWW.. little problem here.
//
// we need to get account from libcore db. in order to do that we have to:
// 1) get wallet using a wallet identifier
// 2) get account from wallet using `rawAccount.index`
//
// Here is the problem: the wallet identifier is currently built like that:
// `${publicKey}__${currencyId}${isSegwit ? '_segwit' : ''}`
//
// and to get the `publicKey` we need the device.
//
// BUT we don't want the device to be required to access ledger-live
// SO.. it's a problem.
//
// Solution 1: store wallet identifier inside the Account (uurgh...)
// Solution 2: stop this project
export async function syncAccount({
rawAccount,
core,
njsWalletPool,
}: {
core: Object,
rawAccount: AccountRaw,
njsWalletPool: Object,
}) {
const decodedAccountId = accountId.decode(rawAccount.id)
const njsWallet = await njsWalletPool.getWallet(decodedAccountId.walletName)
const njsAccount = await njsWallet.getAccount(rawAccount.index)
return {
...rawAccount,
balance: 424242424242,
}
await core.syncAccount(njsAccount)
const query = njsAccount.queryOperations()
const ops = await query.complete().execute()
const njsBalance = await njsAccount.getBalance()
const syncedRawAccount = await buildAccountRaw({
njsAccount,
isSegwit: rawAccount.isSegwit === true,
accountIndex: rawAccount.index,
wallet: njsWallet,
currencyId: rawAccount.currencyId,
core,
ops,
})
syncedRawAccount.balance = njsBalance.toLong()
console.log(`Synced account [${syncedRawAccount.name}]: ${syncedRawAccount.balance}`)
return syncedRawAccount
}

19
src/helpers/withLibcore.js

@ -2,23 +2,26 @@
const core = require('@ledgerhq/ledger-core')
let instanciated = false
let walletPool = null
let queue = Promise.resolve()
// TODO: `core` should be typed
type Job = Object => Promise<any>
// TODO: `core` and `NJSWalletPool` should be typed
type Job = (Object, Object) => any
export default function withLibcore(job: Job) {
if (!instanciated) {
core.instanciateWalletPool({
if (!walletPool) {
walletPool = core.instanciateWalletPool({
// sqlite files will be located in the app local data folder
dbPath: process.env.LEDGER_LIVE_SQLITE_PATH,
})
instanciated = true
}
queue = queue.then(() => {
// $FlowFixMe WTF is happening here, dudes.
queue = queue.then(async () => {
try {
return job(core)
if (!walletPool) {
throw new Error('wallet pool not instanciated. this should not happen')
}
return job(core, walletPool)
} catch (e) {
console.log(`withLibCore: Error in job`, e) // eslint-disable-line no-console
return Promise.resolve()

Loading…
Cancel
Save