Browse Source

introduce 'canBeSpent'

master
Gaëtan Renaudeau 7 years ago
parent
commit
f8ee869a3d
  1. 3
      src/bridge/EthereumJSBridge.js
  2. 22
      src/bridge/EthereumMockJSBridge.js
  3. 6
      src/bridge/LibcoreBridge.js
  4. 29
      src/bridge/RippleJSBridge.js
  5. 2
      src/bridge/UnsupportedBridge.js
  6. 3
      src/bridge/makeMockBridge.js
  7. 2
      src/bridge/types.js
  8. 16
      src/components/modals/Send/Footer.js

3
src/bridge/EthereumJSBridge.js

@ -305,8 +305,9 @@ const EthereumBridge: WalletBridge<Transaction> = {
// $FlowFixMe
EditFees,
// FIXME gasPrice calc is wrong... need to multiply with gasLimit I guess ?
canBeSpent: (a, t) => Promise.resolve(t.amount + t.gasPrice <= a.balance),
getTotalSpent: (a, t) => Promise.resolve(t.amount + t.gasPrice),
getMaxAmount: (a, t) => Promise.resolve(a.balance - t.gasPrice),
signAndBroadcast: async (a, t, deviceId) => {

22
src/bridge/EthereumMockJSBridge.js

@ -1,22 +0,0 @@
// @flow
import React from 'react'
import EthereumKind from 'components/FeesField/EthereumKind'
import type { EditProps } from './types'
import makeMockBridge from './makeMockBridge'
const EditFees = ({ account, onChange, value }: EditProps<*>) => (
<EthereumKind
onChange={gasPrice => {
onChange({ ...value, gasPrice })
}}
gasPrice={value.gasPrice}
account={account}
/>
)
export default makeMockBridge({
extraInitialTransactionProps: () => ({ gasPrice: 0 }),
EditFees,
getTotalSpent: (a, t) => Promise.resolve(t.amount + t.gasPrice),
getMaxAmount: (a, t) => Promise.resolve(a.balance - t.gasPrice),
})

6
src/bridge/LibcoreBridge.js

@ -159,9 +159,11 @@ const LibcoreBridge: WalletBridge<Transaction> = {
isValidTransaction: (a, t) => (t.amount > 0 && t.recipient && true) || false,
getTotalSpent: (a, t) => Promise.resolve(t.amount + t.feePerByte),
canBeSpent: (a, t) => Promise.resolve(t.amount <= a.balance), // FIXME
getMaxAmount: (a, t) => Promise.resolve(a.balance - t.feePerByte),
getTotalSpent: (a, t) => Promise.resolve(t.amount), // FIXME
getMaxAmount: (a, _t) => Promise.resolve(a.balance), // FIXME
signAndBroadcast: (account, transaction, deviceId) => {
const rawAccount = encodeAccount(account)

29
src/bridge/RippleJSBridge.js

@ -2,6 +2,7 @@
import React from 'react'
import bs58check from 'ripple-bs58check'
import { computeBinaryTransactionHash } from 'ripple-hashes'
import throttle from 'lodash/throttle'
import type { Account, Operation } from '@ledgerhq/live-common/lib/types'
import { getDerivations } from 'helpers/derivations'
import getAddress from 'commands/getAddress'
@ -148,6 +149,25 @@ const txToOperation = (account: Account) => ({
return op
}
const getServerInfo = (perCurrencyId => currency => {
if (perCurrencyId[currency.id]) return perCurrencyId[currency.id]()
const f = throttle(async () => {
const api = apiForCurrency(currency)
try {
await api.connect()
const res = await api.getServerInfo()
return res
} catch (e) {
f.cancel()
throw e
} finally {
api.disconnect()
}
}, 60000)
perCurrencyId[currency.id] = f
return f()
})({})
const RippleJSBridge: WalletBridge<Transaction> = {
scanAccountsOnDevice(currency, deviceId, { next, complete, error }) {
let finished = false
@ -159,7 +179,7 @@ const RippleJSBridge: WalletBridge<Transaction> = {
const api = apiForCurrency(currency)
try {
await api.connect()
const serverInfo = await api.getServerInfo()
const serverInfo = await getServerInfo(currency)
const ledgers = serverInfo.completeLedgers.split('-')
const minLedgerVersion = Number(ledgers[0])
const maxLedgerVersion = Number(ledgers[1])
@ -269,7 +289,7 @@ const RippleJSBridge: WalletBridge<Transaction> = {
try {
await api.connect()
if (finished) return
const serverInfo = await api.getServerInfo()
const serverInfo = await getServerInfo(currency)
if (finished) return
const ledgers = serverInfo.completeLedgers.split('-')
const minLedgerVersion = Number(ledgers[0])
@ -371,6 +391,11 @@ const RippleJSBridge: WalletBridge<Transaction> = {
isValidTransaction: (a, t) => (t.amount > 0 && t.recipient && true) || false,
canBeSpent: async (a, t) => {
const r = await getServerInfo(a.currency)
return t.amount + t.fee + parseAPIValue(r.validatedLedger.reserveBaseXRP) <= a.balance
},
getTotalSpent: (a, t) => Promise.resolve(t.amount + t.fee),
getMaxAmount: (a, t) => Promise.resolve(a.balance - t.fee),

2
src/bridge/UnsupportedBridge.js

@ -30,6 +30,8 @@ const UnsupportedBridge: WalletBridge<*> = {
getTransactionRecipient: () => '',
canBeSpent: () => Promise.resolve(false),
getTotalSpent: () => Promise.resolve(0),
getMaxAmount: () => Promise.resolve(0),

3
src/bridge/makeMockBridge.js

@ -30,6 +30,7 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
extraInitialTransactionProps,
getTotalSpent,
getMaxAmount,
canBeSpent,
} = {
...defaultOpts,
...opts,
@ -143,6 +144,8 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
isValidTransaction: (a, t) => (t.amount > 0 && t.recipient && true) || false,
canBeSpent,
getTotalSpent,
getMaxAmount,

2
src/bridge/types.js

@ -84,6 +84,8 @@ export interface WalletBridge<Transaction> {
// render the whole advanced part of the form
EditAdvancedOptions?: React$ComponentType<EditProps<Transaction>>;
canBeSpent(account: Account, transaction: Transaction): Promise<boolean>;
getTotalSpent(account: Account, transaction: Transaction): Promise<number>;
// NB this is not used yet but we'll use it when we have MAX

16
src/components/modals/Send/Footer.js

@ -32,9 +32,16 @@ const mapStateToProps = createStructuredSelector({
exchange: exchangeSettingsForAccountSelector,
})
class Footer extends PureComponent<Props, { totalSpent: number }> {
class Footer extends PureComponent<
Props,
{
totalSpent: number,
canBeSpent: boolean,
},
> {
state = {
totalSpent: 0,
canBeSpent: true,
}
componentDidMount() {
this.resync()
@ -54,12 +61,13 @@ class Footer extends PureComponent<Props, { totalSpent: number }> {
async resync() {
const { account, bridge, transaction } = this.props
const totalSpent = await bridge.getTotalSpent(account, transaction)
const canBeSpent = await bridge.canBeSpent(account, transaction)
if (this.unmount) return
this.setState({ totalSpent })
this.setState({ totalSpent, canBeSpent })
}
render() {
const { exchange, account, t, onNext, canNext, showTotal } = this.props
const { totalSpent } = this.state
const { totalSpent, canBeSpent } = this.state
return (
<ModalFooter>
<Box horizontal alignItems="center" justifyContent="flex-end" flow={2}>
@ -69,7 +77,7 @@ class Footer extends PureComponent<Props, { totalSpent: number }> {
<Box horizontal flow={2} align="center">
<FormattedVal
disableRounding
color={totalSpent > account.balance ? 'pearl' : 'dark'}
color={!canBeSpent ? 'pearl' : 'dark'}
val={totalSpent}
unit={account.unit}
showCode

Loading…
Cancel
Save