Meriadec Pillet
7 years ago
committed by
GitHub
22 changed files with 585 additions and 268 deletions
@ -0,0 +1,111 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React, { PureComponent } from 'react' |
||||
|
import { connect } from 'react-redux' |
||||
|
import { ipcRenderer } from 'electron' |
||||
|
|
||||
|
import { sendEvent } from 'renderer/events' |
||||
|
import { getCurrentDevice } from 'reducers/devices' |
||||
|
import type { Device, Account } from 'types/common' |
||||
|
|
||||
|
const mapStateToProps = state => ({ |
||||
|
currentDevice: getCurrentDevice(state), |
||||
|
}) |
||||
|
|
||||
|
type DeviceStatus = 'unconnected' | 'connected' | 'appOpened' |
||||
|
|
||||
|
type Props = { |
||||
|
currentDevice: Device | null, |
||||
|
account: Account, |
||||
|
onStatusChange: DeviceStatus => void, |
||||
|
} |
||||
|
|
||||
|
type State = { |
||||
|
status: DeviceStatus, |
||||
|
} |
||||
|
|
||||
|
class DeviceMonit extends PureComponent<Props, State> { |
||||
|
state = { |
||||
|
status: this.props.currentDevice ? 'connected' : 'unconnected', |
||||
|
} |
||||
|
|
||||
|
componentDidMount() { |
||||
|
ipcRenderer.on('msg', this.handleMsgEvent) |
||||
|
if (this.props.currentDevice !== null) { |
||||
|
this.checkAppOpened() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
componentWillReceiveProps(nextProps) { |
||||
|
const { status } = this.state |
||||
|
const { currentDevice } = this.props |
||||
|
const { currentDevice: nextCurrentDevice } = nextProps |
||||
|
|
||||
|
if (status === 'unconnected' && !currentDevice && nextCurrentDevice) { |
||||
|
this.handleStatusChange('connected') |
||||
|
} |
||||
|
|
||||
|
if (status !== 'unconnected' && !nextCurrentDevice) { |
||||
|
this.handleStatusChange('unconnected') |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
componentDidUpdate() { |
||||
|
const { currentDevice } = this.props |
||||
|
|
||||
|
if (currentDevice !== null) { |
||||
|
this.checkAppOpened() |
||||
|
} else { |
||||
|
clearTimeout(this._timeout) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
componentWillUnmount() { |
||||
|
ipcRenderer.removeListener('msg', this.handleMsgEvent) |
||||
|
clearTimeout(this._timeout) |
||||
|
} |
||||
|
|
||||
|
checkAppOpened = () => { |
||||
|
const { currentDevice, account } = this.props |
||||
|
|
||||
|
if (currentDevice === null || account.currency === null) { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
sendEvent('usb', 'wallet.checkIfAppOpened', { |
||||
|
devicePath: currentDevice.path, |
||||
|
accountPath: account.path, |
||||
|
accountAddress: account.address, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
_timeout: any = null |
||||
|
|
||||
|
handleStatusChange = status => { |
||||
|
this.setState({ status }) |
||||
|
this.props.onStatusChange(status) |
||||
|
} |
||||
|
|
||||
|
handleMsgEvent = (e, { type }) => { |
||||
|
if (type === 'wallet.checkIfAppOpened.success') { |
||||
|
this.handleStatusChange('appOpened') |
||||
|
clearTimeout(this._timeout) |
||||
|
} |
||||
|
|
||||
|
if (type === 'wallet.checkIfAppOpened.fail') { |
||||
|
this._timeout = setTimeout(this.checkAppOpened, 1e3) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
render() { |
||||
|
const { status } = this.state |
||||
|
return ( |
||||
|
<div> |
||||
|
<div>device connected {status !== 'unconnected' ? 'TRUE' : 'FALSE'}</div> |
||||
|
<div>app opened {status === 'appOpened' ? 'TRUE' : 'FALSE'}</div> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(DeviceMonit) |
@ -0,0 +1,24 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React from 'react' |
||||
|
|
||||
|
import Box from 'components/base/Box' |
||||
|
import Tooltip from 'components/base/Tooltip' |
||||
|
import IconInfoCircle from 'icons/InfoCircle' |
||||
|
|
||||
|
type Props = { |
||||
|
text: string, |
||||
|
} |
||||
|
|
||||
|
function LabelInfoTooltip(props: Props) { |
||||
|
const { text, ...p } = props |
||||
|
return ( |
||||
|
<Box {...p}> |
||||
|
<Tooltip render={() => text} style={{ height: 12 }}> |
||||
|
<IconInfoCircle width={12} height={12} /> |
||||
|
</Tooltip> |
||||
|
</Box> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default LabelInfoTooltip |
@ -1,179 +0,0 @@ |
|||||
// @flow
|
|
||||
|
|
||||
import React, { PureComponent } from 'react' |
|
||||
import { translate } from 'react-i18next' |
|
||||
import get from 'lodash/get' |
|
||||
import { getDefaultUnitByCoinType } from '@ledgerhq/currencies' |
|
||||
|
|
||||
import type { T } from 'types/common' |
|
||||
|
|
||||
import { MODAL_SEND } from 'constants' |
|
||||
|
|
||||
import Box from 'components/base/Box' |
|
||||
import Button from 'components/base/Button' |
|
||||
import Input from 'components/base/Input' |
|
||||
import Label from 'components/base/Label' |
|
||||
import Modal, { ModalBody, ModalTitle, ModalFooter, ModalContent } from 'components/base/Modal' |
|
||||
import Breadcrumb from 'components/Breadcrumb' |
|
||||
import RecipientAddress from 'components/RecipientAddress' |
|
||||
import SelectAccount from 'components/SelectAccount' |
|
||||
import FormattedVal from 'components/base/FormattedVal' |
|
||||
|
|
||||
const Steps = { |
|
||||
'1': ({ t, ...props }: Object) => ( |
|
||||
<form |
|
||||
onSubmit={(e: SyntheticEvent<HTMLFormElement>) => { |
|
||||
e.preventDefault() |
|
||||
|
|
||||
if (props.canSubmit) { |
|
||||
props.onChangeStep('2') |
|
||||
} |
|
||||
}} |
|
||||
> |
|
||||
<Box flow={4}> |
|
||||
<Box flow={1}> |
|
||||
<Label>Account to debit</Label> |
|
||||
<SelectAccount onChange={props.onChangeInput('account')} value={props.value.account} /> |
|
||||
</Box> |
|
||||
<Box flow={1}> |
|
||||
<Label>Recipient address</Label> |
|
||||
<RecipientAddress onChange={props.onChangeInput('address')} value={props.value.address} /> |
|
||||
</Box> |
|
||||
<Box flow={1}> |
|
||||
<Label>Amount</Label> |
|
||||
<Input onChange={props.onChangeInput('amount')} value={props.value.amount} /> |
|
||||
</Box> |
|
||||
</Box> |
|
||||
</form> |
|
||||
), |
|
||||
'2': (props: Object) => ( |
|
||||
<div> |
|
||||
<div>summary</div> |
|
||||
<div>{props.value.amount}</div> |
|
||||
<div>to {props.value.address}</div> |
|
||||
<div>from {props.value.account.name}</div> |
|
||||
</div> |
|
||||
), |
|
||||
} |
|
||||
|
|
||||
type InputValue = { |
|
||||
account: any, |
|
||||
address: string, |
|
||||
amount: string, |
|
||||
} |
|
||||
|
|
||||
type Step = '1' | '2' |
|
||||
|
|
||||
type State = { |
|
||||
inputValue: InputValue, |
|
||||
step: Step, |
|
||||
} |
|
||||
|
|
||||
type Props = { |
|
||||
t: T, |
|
||||
} |
|
||||
|
|
||||
const defaultState = { |
|
||||
inputValue: { |
|
||||
account: null, |
|
||||
address: '', |
|
||||
amount: '', |
|
||||
}, |
|
||||
step: '1', |
|
||||
} |
|
||||
|
|
||||
class Send extends PureComponent<Props, State> { |
|
||||
state = { |
|
||||
...defaultState, |
|
||||
} |
|
||||
|
|
||||
getStepProps(data: any) { |
|
||||
const { inputValue, step } = this.state |
|
||||
const { t } = this.props |
|
||||
|
|
||||
const props = (predicate, props, defaults = {}) => (predicate ? props : defaults) |
|
||||
|
|
||||
const account = inputValue.account || get(data, 'account') |
|
||||
|
|
||||
return { |
|
||||
...props(step === '1', { |
|
||||
canSubmit: account && inputValue.address.trim() !== '' && inputValue.amount.trim() !== '', |
|
||||
onChangeInput: this.handleChangeInput, |
|
||||
value: { |
|
||||
...inputValue, |
|
||||
account, |
|
||||
}, |
|
||||
}), |
|
||||
...props(step === '2', { |
|
||||
value: { |
|
||||
...inputValue, |
|
||||
account, |
|
||||
}, |
|
||||
}), |
|
||||
onChangeStep: this.handleChangeStep, |
|
||||
t, |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
handleChangeInput = (key: $Keys<InputValue>) => (value: $Values<InputValue>) => |
|
||||
this.setState(prev => ({ |
|
||||
inputValue: { |
|
||||
...prev.inputValue, |
|
||||
[key]: value, |
|
||||
}, |
|
||||
})) |
|
||||
|
|
||||
handleChangeStep = (step: Step) => |
|
||||
this.setState({ |
|
||||
step, |
|
||||
}) |
|
||||
|
|
||||
handleHide = () => |
|
||||
this.setState({ |
|
||||
...defaultState, |
|
||||
}) |
|
||||
|
|
||||
_steps = [ |
|
||||
'sendModal:Amount', |
|
||||
'sendModal:Summary', |
|
||||
'sendModal:SecureValidation', |
|
||||
'sendModal:Confirmation', |
|
||||
].map(v => ({ label: this.props.t(v) })) |
|
||||
|
|
||||
render() { |
|
||||
const { step } = this.state |
|
||||
const { t } = this.props |
|
||||
const Step = Steps[step] |
|
||||
return ( |
|
||||
<Modal |
|
||||
name={MODAL_SEND} |
|
||||
onHide={this.handleHide} |
|
||||
render={({ data, onClose }) => ( |
|
||||
<ModalBody onClose={onClose}> |
|
||||
<ModalTitle>{t('send:title')}</ModalTitle> |
|
||||
<ModalContent> |
|
||||
<Box mb={6} mt={2}> |
|
||||
<Breadcrumb currentStep={step} items={this._steps} /> |
|
||||
</Box> |
|
||||
<Step {...this.getStepProps(data)} /> |
|
||||
</ModalContent> |
|
||||
<ModalFooter horizontal align="center"> |
|
||||
<Box grow> |
|
||||
<Label>{'Total spent'}</Label> |
|
||||
<FormattedVal |
|
||||
color="dark" |
|
||||
val={15496420404} |
|
||||
unit={getDefaultUnitByCoinType(0)} |
|
||||
showCode |
|
||||
/> |
|
||||
</Box> |
|
||||
<Button primary>{'Next'}</Button> |
|
||||
</ModalFooter> |
|
||||
</ModalBody> |
|
||||
)} |
|
||||
/> |
|
||||
) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export default translate()(Send) |
|
@ -0,0 +1,73 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React, { Fragment } from 'react' |
||||
|
|
||||
|
import type { Account, T } from 'types/common' |
||||
|
import type { DoubleVal } from 'components/RequestAmount' |
||||
|
|
||||
|
import Box from 'components/base/Box' |
||||
|
import SelectAccount from 'components/SelectAccount' |
||||
|
import Label from 'components/base/Label' |
||||
|
import LabelInfoTooltip from 'components/base/LabelInfoTooltip' |
||||
|
import RecipientAddress from 'components/RecipientAddress' |
||||
|
import RequestAmount from 'components/RequestAmount' |
||||
|
import Select from 'components/base/Select' |
||||
|
import Input from 'components/base/Input' |
||||
|
|
||||
|
type Props = { |
||||
|
account: Account | null, |
||||
|
onChange: Function, |
||||
|
recipientAddress: string, |
||||
|
amount: DoubleVal, |
||||
|
t: T, |
||||
|
} |
||||
|
|
||||
|
function StepAmount(props: Props) { |
||||
|
const { onChange, account, recipientAddress, t, amount } = props |
||||
|
|
||||
|
return ( |
||||
|
<Box flow={4}> |
||||
|
<Box flow={1}> |
||||
|
<Label>{t('send:steps.amount.selectAccountDebit')}</Label> |
||||
|
<SelectAccount onChange={onChange('account')} value={account} /> |
||||
|
</Box> |
||||
|
<Box flow={1}> |
||||
|
<Label> |
||||
|
<span>{t('send:steps.amount.recipientAddress')}</span> |
||||
|
<LabelInfoTooltip ml={1} text={t('send:steps.amount.recipientAddress')} /> |
||||
|
</Label> |
||||
|
<RecipientAddress |
||||
|
withQrCode |
||||
|
value={recipientAddress} |
||||
|
onChange={onChange('recipientAddress')} |
||||
|
/> |
||||
|
</Box> |
||||
|
{account && ( |
||||
|
<Fragment> |
||||
|
<Box flow={1}> |
||||
|
<Label>{t('send:steps.amount.amount')}</Label> |
||||
|
<RequestAmount account={account} onChange={onChange('amount')} value={amount} /> |
||||
|
</Box> |
||||
|
<Box flow={1}> |
||||
|
<Label> |
||||
|
<span>{t('send:steps.amount.fees')}</span> |
||||
|
<LabelInfoTooltip ml={1} text={t('send:steps.amount.fees')} /> |
||||
|
</Label> |
||||
|
<Box horizontal flow={5}> |
||||
|
<Select |
||||
|
placeholder="Choose a chess player..." |
||||
|
items={[{ key: 'custom', name: 'Custom' }]} |
||||
|
value={{ key: 'custom', name: 'Custom' }} |
||||
|
renderSelected={item => item.name} |
||||
|
onChange={onChange('fees')} |
||||
|
/> |
||||
|
<Input containerProps={{ grow: true }} /> |
||||
|
</Box> |
||||
|
</Box> |
||||
|
</Fragment> |
||||
|
)} |
||||
|
</Box> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default StepAmount |
@ -0,0 +1,37 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React from 'react' |
||||
|
|
||||
|
import DeviceMonit from 'components/DeviceMonit' |
||||
|
import type { Account } from 'types/common' |
||||
|
|
||||
|
type Props = { |
||||
|
account: Account | null, |
||||
|
isDeviceReady: boolean, |
||||
|
onChange: Function, |
||||
|
} |
||||
|
|
||||
|
function StepConnectDevice(props: Props) { |
||||
|
const { account, isDeviceReady, onChange } = props |
||||
|
const setReady = onChange('isDeviceReady') |
||||
|
if (!account) { |
||||
|
return null |
||||
|
} |
||||
|
return ( |
||||
|
<div> |
||||
|
<DeviceMonit |
||||
|
account={account} |
||||
|
onStatusChange={status => { |
||||
|
if (status === 'appOpened' && !isDeviceReady) { |
||||
|
setReady(true) |
||||
|
} |
||||
|
if (status !== 'appOpened' && isDeviceReady) { |
||||
|
setReady(false) |
||||
|
} |
||||
|
}} |
||||
|
/> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default StepConnectDevice |
@ -0,0 +1,7 @@ |
|||||
|
import React from 'react' |
||||
|
|
||||
|
function StepVerification() { |
||||
|
return <div>step verification</div> |
||||
|
} |
||||
|
|
||||
|
export default StepVerification |
@ -0,0 +1,7 @@ |
|||||
|
import React from 'react' |
||||
|
|
||||
|
function StepConfirmation() { |
||||
|
return <div>step confirmation</div> |
||||
|
} |
||||
|
|
||||
|
export default StepConfirmation |
@ -0,0 +1,53 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React from 'react' |
||||
|
|
||||
|
import type { T, Account } from 'types/common' |
||||
|
import type { DoubleVal } from 'components/RequestAmount' |
||||
|
|
||||
|
import { ModalFooter } from 'components/base/Modal' |
||||
|
import Box from 'components/base/Box' |
||||
|
import Label from 'components/base/Label' |
||||
|
import FormattedVal from 'components/base/FormattedVal' |
||||
|
import Button from 'components/base/Button' |
||||
|
import Text from 'components/base/Text' |
||||
|
|
||||
|
type Props = { |
||||
|
t: T, |
||||
|
account: Account, |
||||
|
amount: DoubleVal, |
||||
|
onNext: Function, |
||||
|
canNext: boolean, |
||||
|
} |
||||
|
|
||||
|
function Footer({ account, amount, t, onNext, canNext }: Props) { |
||||
|
return ( |
||||
|
<ModalFooter horizontal align="center"> |
||||
|
<Box grow> |
||||
|
<Label>{t('send:totalSpent')}</Label> |
||||
|
<Box horizontal flow={2} align="center"> |
||||
|
<FormattedVal |
||||
|
color="dark" |
||||
|
val={amount.left * 10 ** account.unit.magnitude} |
||||
|
unit={account.unit} |
||||
|
showCode |
||||
|
/> |
||||
|
<Box horizontal align="center"> |
||||
|
<Text ff="Rubik" fontSize={3}> |
||||
|
{'('} |
||||
|
</Text> |
||||
|
<FormattedVal color="grey" fontSize={3} val={amount.right} fiat="USD" showCode /> |
||||
|
<Text ff="Rubik" fontSize={3}> |
||||
|
{')'} |
||||
|
</Text> |
||||
|
</Box> |
||||
|
</Box> |
||||
|
</Box> |
||||
|
<Button primary onClick={onNext} disabled={!canNext}> |
||||
|
{'Next'} |
||||
|
</Button> |
||||
|
</ModalFooter> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default Footer |
@ -0,0 +1,138 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React, { PureComponent } from 'react' |
||||
|
import { translate } from 'react-i18next' |
||||
|
import get from 'lodash/get' |
||||
|
|
||||
|
import type { T, Account } from 'types/common' |
||||
|
import type { DoubleVal } from 'components/RequestAmount' |
||||
|
|
||||
|
import { MODAL_SEND } from 'constants' |
||||
|
|
||||
|
import Breadcrumb from 'components/Breadcrumb' |
||||
|
import Modal, { ModalBody, ModalTitle, ModalContent } from 'components/base/Modal' |
||||
|
|
||||
|
import Footer from './Footer' |
||||
|
|
||||
|
import StepAmount from './01-step-amount' |
||||
|
import StepConnectDevice from './02-step-connect-device' |
||||
|
import StepVerification from './03-step-verification' |
||||
|
import StepConfirmation from './04-step-confirmation' |
||||
|
|
||||
|
type Props = { |
||||
|
t: T, |
||||
|
} |
||||
|
|
||||
|
type State = { |
||||
|
stepIndex: number, |
||||
|
isDeviceReady: boolean, |
||||
|
amount: DoubleVal, |
||||
|
account: Account | null, |
||||
|
recipientAddress: string, |
||||
|
fees: number, |
||||
|
} |
||||
|
|
||||
|
const GET_STEPS = t => [ |
||||
|
{ label: t('send:steps.amount.title'), Comp: StepAmount }, |
||||
|
{ label: t('send:steps.connectDevice.title'), Comp: StepConnectDevice }, |
||||
|
{ label: t('send:steps.verification.title'), Comp: StepVerification }, |
||||
|
{ label: t('send:steps.confirmation.title'), Comp: StepConfirmation }, |
||||
|
] |
||||
|
|
||||
|
const INITIAL_STATE = { |
||||
|
stepIndex: 0, |
||||
|
isDeviceReady: false, |
||||
|
account: null, |
||||
|
recipientAddress: '', |
||||
|
amount: { |
||||
|
left: 0, |
||||
|
right: 0, |
||||
|
}, |
||||
|
fees: 0, |
||||
|
} |
||||
|
|
||||
|
class SendModal extends PureComponent<Props, State> { |
||||
|
state = INITIAL_STATE |
||||
|
|
||||
|
_steps = GET_STEPS(this.props.t) |
||||
|
|
||||
|
canNext = account => { |
||||
|
const { stepIndex } = this.state |
||||
|
|
||||
|
// informations
|
||||
|
if (stepIndex === 0) { |
||||
|
const { amount, recipientAddress } = this.state |
||||
|
return !!amount.left && !!recipientAddress && !!account |
||||
|
} |
||||
|
|
||||
|
// connect device
|
||||
|
if (stepIndex === 1) { |
||||
|
const { isDeviceReady } = this.state |
||||
|
return !!isDeviceReady |
||||
|
} |
||||
|
|
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
handleReset = () => this.setState(INITIAL_STATE) |
||||
|
|
||||
|
handleNextStep = () => { |
||||
|
const { stepIndex } = this.state |
||||
|
if (stepIndex >= this._steps.length - 1) { |
||||
|
return |
||||
|
} |
||||
|
this.setState({ stepIndex: stepIndex + 1 }) |
||||
|
} |
||||
|
|
||||
|
createChangeHandler = key => value => this.setState({ [key]: value }) |
||||
|
|
||||
|
renderStep = acc => { |
||||
|
const { stepIndex, account } = this.state |
||||
|
const step = this._steps[stepIndex] |
||||
|
if (!step) { |
||||
|
return null |
||||
|
} |
||||
|
const { Comp } = step |
||||
|
const stepProps = { |
||||
|
...this.state, |
||||
|
account: account || acc, |
||||
|
} |
||||
|
return <Comp onChange={this.createChangeHandler} {...stepProps} {...this.props} /> |
||||
|
} |
||||
|
|
||||
|
render() { |
||||
|
const { t } = this.props |
||||
|
const { stepIndex, amount, account } = this.state |
||||
|
|
||||
|
return ( |
||||
|
<Modal |
||||
|
name={MODAL_SEND} |
||||
|
onHide={this.handleReset} |
||||
|
render={({ data, onClose }) => { |
||||
|
const acc = account || get(data, 'account', null) |
||||
|
const canNext = this.canNext(acc) |
||||
|
return ( |
||||
|
<ModalBody onClose={onClose}> |
||||
|
<ModalTitle>{t('send:title')}</ModalTitle> |
||||
|
<ModalContent> |
||||
|
<Breadcrumb mb={6} mt={2} currentStep={stepIndex} items={this._steps} /> |
||||
|
{this.renderStep(acc)} |
||||
|
</ModalContent> |
||||
|
{acc && ( |
||||
|
<Footer |
||||
|
canNext={canNext} |
||||
|
onNext={this.handleNextStep} |
||||
|
account={acc} |
||||
|
amount={amount} |
||||
|
t={t} |
||||
|
/> |
||||
|
)} |
||||
|
</ModalBody> |
||||
|
) |
||||
|
}} |
||||
|
/> |
||||
|
) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default translate()(SendModal) |
@ -0,0 +1,10 @@ |
|||||
|
import React from 'react' |
||||
|
|
||||
|
export default props => ( |
||||
|
<svg viewBox="0 0 16 16" {...props}> |
||||
|
<path |
||||
|
fill="currentColor" |
||||
|
d="M8 .25a7.751 7.751 0 0 0 0 15.5A7.75 7.75 0 1 0 8 .25zm0 14A6.246 6.246 0 0 1 1.75 8 6.248 6.248 0 0 1 8 1.75 6.248 6.248 0 0 1 14.25 8 6.246 6.246 0 0 1 8 14.25zM8 3.687a1.312 1.312 0 1 1 0 2.625 1.312 1.312 0 0 1 0-2.625zm1.75 7.938a.375.375 0 0 1-.375.375h-2.75a.375.375 0 0 1-.375-.375v-.75c0-.207.168-.375.375-.375H7v-2h-.375a.375.375 0 0 1-.375-.375v-.75c0-.207.168-.375.375-.375h2c.207 0 .375.168.375.375V10.5h.375c.207 0 .375.168.375.375v.75z" |
||||
|
/> |
||||
|
</svg> |
||||
|
) |
@ -1,5 +1,17 @@ |
|||||
title: Send |
title: Send funds |
||||
Amount: Amount |
totalSpent: Total spent |
||||
Summary: Summary |
steps: |
||||
SecureValidation: Secure validation |
amount: |
||||
Confirmation: Confirmation |
title: Informations |
||||
|
selectAccountDebit: Select an account to debit |
||||
|
recipientAddress: Recipient address |
||||
|
amount: Amount |
||||
|
max: Max |
||||
|
fees: Fees |
||||
|
advancedOptions: Advanced options |
||||
|
connectDevice: |
||||
|
title: Connect device |
||||
|
verification: |
||||
|
title: Verification |
||||
|
confirmation: |
||||
|
title: Confirmation |
||||
|
Loading…
Reference in new issue