[beta] UI backports (#4809)
* Update Wallet to new Wallet Code (#4805) * Update Wallet Version * Update Wallet Library * Update Wallets Bytecodes * Typo * Separate Deploy in Contract API * Use the new Wallet ABI // Update wallet code * WIP .// Deploy from Wallet * Update Wallet contract * Contract Deployment for Wallet * Working deployments for Single Owned Wallet contracts * Linting * Create a Wallet from a Wallet * Linting * Fix Signer transactions // Add Gas Used for transactions * Deploy wallet contract fix * Fix too high gas estimate for Wallet Contract Deploys * Final piece ; deploying from Wallet owned by wallet * Update Wallet Code * Updated the Wallet Codes * Fixing Wallet Deployments * Add Support for older wallets * Linting * SMS Faucet (#4774) * Faucet * Remove flakey button-index testing * Only display faucet when sms verified (mainnet) * simplify availability checks * WIP * Resuest from verified -> verified * Update endpoint, display response text * Error icon on errors * Parse hash text response * Use /api/:address endpoint * hash -> data * Adjust sms-certified message * Fix SectionList hovering issue (#4749) * Fix SectionList Items hover when <3 items * Even easier... * lint (new)
This commit is contained in:
committed by
Arkadiy Paronyan
parent
3b56e8eded
commit
c4196a5de3
@@ -14,7 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { omitBy } from 'lodash';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
@@ -106,9 +105,6 @@ export default class WalletDetails extends Component {
|
||||
renderMultisigDetails () {
|
||||
const { accounts, wallet, errors } = this.props;
|
||||
|
||||
// Wallets cannot create contracts
|
||||
const _accounts = omitBy(accounts, (a) => a.wallet);
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<Input
|
||||
@@ -148,7 +144,7 @@ export default class WalletDetails extends Component {
|
||||
/>
|
||||
|
||||
<AddressSelect
|
||||
accounts={ _accounts }
|
||||
accounts={ accounts }
|
||||
error={ errors.account }
|
||||
hint={
|
||||
<FormattedMessage
|
||||
|
||||
@@ -22,10 +22,11 @@ import Contract from '~/api/contract';
|
||||
import { ERROR_CODES } from '~/api/transport/error';
|
||||
import Contracts from '~/contracts';
|
||||
import { wallet as walletAbi } from '~/contracts/abi';
|
||||
import { wallet as walletCode, walletLibraryRegKey, fullWalletCode } from '~/contracts/code/wallet';
|
||||
import { wallet as walletCode, walletLibrary as walletLibraryCode, walletLibraryRegKey, fullWalletCode } from '~/contracts/code/wallet';
|
||||
|
||||
import { validateUint, validateAddress, validateName } from '~/util/validation';
|
||||
import { toWei } from '~/api/util/wei';
|
||||
import { deploy } from '~/util/tx';
|
||||
import WalletsUtils from '~/util/wallets';
|
||||
|
||||
const STEPS = {
|
||||
@@ -179,6 +180,8 @@ export default class CreateWalletStore {
|
||||
this.wallet.owners = owners;
|
||||
this.wallet.required = require.toNumber();
|
||||
this.wallet.dailylimit = dailylimit.limit;
|
||||
|
||||
this.wallet = this.getWalletWithMeta(this.wallet);
|
||||
});
|
||||
|
||||
return this.addWallet(this.wallet);
|
||||
@@ -202,21 +205,51 @@ export default class CreateWalletStore {
|
||||
return null; // exception when registry is not available
|
||||
})
|
||||
.then((address) => {
|
||||
const walletLibraryAddress = (address || '').replace(/^0x/, '').toLowerCase();
|
||||
const code = walletLibraryAddress.length && !/^0+$/.test(walletLibraryAddress)
|
||||
? walletCode.replace(/(_)+WalletLibrary(_)+/g, walletLibraryAddress)
|
||||
: fullWalletCode;
|
||||
if (!address || /^(0x)?0*$/.test(address)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check that it's actually the expected code
|
||||
return this.api.eth
|
||||
.getCode(address)
|
||||
.then((code) => {
|
||||
const strippedCode = code.replace(/^0x/, '');
|
||||
|
||||
// The actual deployed code is included in the wallet
|
||||
// library code (which might have some more data)
|
||||
if (walletLibraryCode.indexOf(strippedCode) >= 0) {
|
||||
return address;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
})
|
||||
.then((address) => {
|
||||
let code = fullWalletCode;
|
||||
|
||||
if (address) {
|
||||
const walletLibraryAddress = address.replace(/^0x/, '').toLowerCase();
|
||||
|
||||
code = walletCode.replace(/(_)+WalletLibrary(_)+/g, walletLibraryAddress);
|
||||
} else {
|
||||
console.warn('wallet library has not been found in the registry');
|
||||
}
|
||||
|
||||
const options = {
|
||||
data: code,
|
||||
from: account
|
||||
};
|
||||
|
||||
return this.api
|
||||
.newContract(walletAbi)
|
||||
.deploy(options, [ owners, required, daylimit ], this.onDeploymentState);
|
||||
const contract = this.api.newContract(walletAbi);
|
||||
|
||||
this.wallet = this.getWalletWithMeta(this.wallet);
|
||||
return deploy(contract, options, [ owners, required, daylimit ], this.wallet.metadata, this.onDeploymentState);
|
||||
})
|
||||
.then((address) => {
|
||||
if (!address || /^(0x)?0*$/.test(address)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.deployed = true;
|
||||
this.wallet.address = address;
|
||||
return this.addWallet(this.wallet);
|
||||
@@ -233,26 +266,37 @@ export default class CreateWalletStore {
|
||||
}
|
||||
|
||||
@action addWallet = (wallet) => {
|
||||
const { address, name, description } = wallet;
|
||||
const { address, name, metadata } = wallet;
|
||||
|
||||
return Promise
|
||||
.all([
|
||||
this.api.parity.setAccountName(address, name),
|
||||
this.api.parity.setAccountMeta(address, {
|
||||
abi: walletAbi,
|
||||
wallet: true,
|
||||
timestamp: Date.now(),
|
||||
deleted: false,
|
||||
description,
|
||||
name,
|
||||
tags: ['wallet']
|
||||
})
|
||||
this.api.parity.setAccountMeta(address, metadata)
|
||||
])
|
||||
.then(() => {
|
||||
this.step = 'INFO';
|
||||
});
|
||||
}
|
||||
|
||||
getWalletWithMeta = (wallet) => {
|
||||
const { name, description } = wallet;
|
||||
|
||||
const metadata = {
|
||||
abi: walletAbi,
|
||||
wallet: true,
|
||||
timestamp: Date.now(),
|
||||
deleted: false,
|
||||
tags: [ 'wallet' ],
|
||||
description,
|
||||
name
|
||||
};
|
||||
|
||||
return {
|
||||
...wallet,
|
||||
metadata
|
||||
};
|
||||
}
|
||||
|
||||
onDeploymentState = (error, data) => {
|
||||
if (error) {
|
||||
return console.error('createWallet::onDeploymentState', error);
|
||||
@@ -298,6 +342,15 @@ export default class CreateWalletStore {
|
||||
);
|
||||
return;
|
||||
|
||||
case 'confirmationNeeded':
|
||||
this.deployState = (
|
||||
<FormattedMessage
|
||||
id='createWallet.states.confirmationNeeded'
|
||||
defaultMessage='The contract deployment needs confirmations from other owners of the Wallet'
|
||||
/>
|
||||
);
|
||||
return;
|
||||
|
||||
case 'completed':
|
||||
this.deployState = (
|
||||
<FormattedMessage
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { pick, omitBy } from 'lodash';
|
||||
import { pick } from 'lodash';
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
@@ -23,6 +23,7 @@ import { connect } from 'react-redux';
|
||||
import { BusyStep, Button, CompletedStep, CopyToClipboard, GasPriceEditor, IdentityIcon, Portal, TxHash, Warning } from '~/ui';
|
||||
import { CancelIcon, DoneIcon } from '~/ui/Icons';
|
||||
import { ERRORS, validateAbi, validateCode, validateName } from '~/util/validation';
|
||||
import { deploy, deployEstimateGas } from '~/util/tx';
|
||||
|
||||
import DetailsStep from './DetailsStep';
|
||||
import ParametersStep from './ParametersStep';
|
||||
@@ -73,7 +74,7 @@ class DeployContract extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired,
|
||||
store: PropTypes.object.isRequired
|
||||
}
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object.isRequired,
|
||||
@@ -422,9 +423,9 @@ class DeployContract extends Component {
|
||||
from: fromAddress
|
||||
};
|
||||
|
||||
api
|
||||
.newContract(abiParsed)
|
||||
.deployEstimateGas(options, params)
|
||||
const contract = api.newContract(abiParsed);
|
||||
|
||||
deployEstimateGas(contract, options, params)
|
||||
.then(([gasEst, gas]) => {
|
||||
this.gasStore.setEstimated(gasEst.toFixed(0));
|
||||
this.gasStore.setGas(gas.toFixed(0));
|
||||
@@ -490,6 +491,17 @@ class DeployContract extends Component {
|
||||
const { api, store } = this.context;
|
||||
const { source } = this.props;
|
||||
const { abiParsed, code, description, name, params, fromAddress } = this.state;
|
||||
|
||||
const metadata = {
|
||||
abi: abiParsed,
|
||||
contract: true,
|
||||
deleted: false,
|
||||
timestamp: Date.now(),
|
||||
name,
|
||||
description,
|
||||
source
|
||||
};
|
||||
|
||||
const options = {
|
||||
data: code,
|
||||
from: fromAddress
|
||||
@@ -499,28 +511,25 @@ class DeployContract extends Component {
|
||||
|
||||
const contract = api.newContract(abiParsed);
|
||||
|
||||
contract
|
||||
.deploy(options, params, this.onDeploymentState)
|
||||
deploy(contract, options, params, metadata, this.onDeploymentState)
|
||||
.then((address) => {
|
||||
const blockNumber = contract._receipt
|
||||
// No contract address given, might need some confirmations
|
||||
// from the wallet owners...
|
||||
if (!address || /^(0x)?0*$/.test(address)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
metadata.blockNumber = contract._receipt
|
||||
? contract.receipt.blockNumber.toNumber()
|
||||
: null;
|
||||
|
||||
return Promise.all([
|
||||
api.parity.setAccountName(address, name),
|
||||
api.parity.setAccountMeta(address, {
|
||||
abi: abiParsed,
|
||||
contract: true,
|
||||
timestamp: Date.now(),
|
||||
deleted: false,
|
||||
blockNumber,
|
||||
description,
|
||||
source
|
||||
})
|
||||
api.parity.setAccountMeta(address, metadata)
|
||||
])
|
||||
.then(() => {
|
||||
console.log(`contract deployed at ${address}`);
|
||||
this.setState({ step: 'DEPLOYMENT', address });
|
||||
this.setState({ step: 'COMPLETED', address });
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
@@ -589,6 +598,17 @@ class DeployContract extends Component {
|
||||
});
|
||||
return;
|
||||
|
||||
case 'confirmationNeeded':
|
||||
this.setState({
|
||||
deployState: (
|
||||
<FormattedMessage
|
||||
id='deployContract.state.confirmationNeeded'
|
||||
defaultMessage='The operation needs confirmations from the other owners of the contract'
|
||||
/>
|
||||
)
|
||||
});
|
||||
return;
|
||||
|
||||
case 'completed':
|
||||
this.setState({
|
||||
deployState: (
|
||||
@@ -614,17 +634,14 @@ class DeployContract extends Component {
|
||||
function mapStateToProps (initState, initProps) {
|
||||
const { accounts } = initProps;
|
||||
|
||||
// Skip Wallet accounts : they can't create Contracts
|
||||
const _accounts = omitBy(accounts, (a) => a.wallet);
|
||||
|
||||
const fromAddresses = Object.keys(_accounts);
|
||||
const fromAddresses = Object.keys(accounts);
|
||||
|
||||
return (state) => {
|
||||
const balances = pick(state.balances.balances, fromAddresses);
|
||||
const { gasLimit } = state.nodeStatus;
|
||||
|
||||
return {
|
||||
accounts: _accounts,
|
||||
accounts,
|
||||
balances,
|
||||
gasLimit
|
||||
};
|
||||
|
||||
162
js/src/modals/Faucet/faucet.js
Normal file
162
js/src/modals/Faucet/faucet.js
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { txLink } from '~/3rdparty/etherscan/links';
|
||||
import { Button, ModalBox, Portal, ShortenedHash } from '~/ui';
|
||||
import { CloseIcon, DialIcon, DoneIcon, ErrorIcon, SendIcon } from '~/ui/Icons';
|
||||
|
||||
import Store from './store';
|
||||
|
||||
@observer
|
||||
export default class Faucet extends Component {
|
||||
static propTypes = {
|
||||
address: PropTypes.string.isRequired,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
onClose: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
store = new Store(this.props.netVersion, this.props.address);
|
||||
|
||||
render () {
|
||||
const { error, isBusy, isCompleted } = this.store;
|
||||
|
||||
let icon = <DialIcon />;
|
||||
|
||||
if (isCompleted) {
|
||||
icon = error
|
||||
? <ErrorIcon />
|
||||
: <DoneIcon />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Portal
|
||||
buttons={ this.renderActions() }
|
||||
busy={ isBusy }
|
||||
isSmallModal
|
||||
onClose={ this.onClose }
|
||||
open
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='faucet.title'
|
||||
defaultMessage='Kovan ETH Faucet'
|
||||
/>
|
||||
}
|
||||
>
|
||||
<ModalBox
|
||||
icon={ icon }
|
||||
summary={
|
||||
isCompleted
|
||||
? this.renderSummaryDone()
|
||||
: this.renderSummaryRequest()
|
||||
}
|
||||
/>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
|
||||
renderActions = () => {
|
||||
const { canTransact, isBusy, isCompleted } = this.store;
|
||||
|
||||
return isCompleted || isBusy
|
||||
? (
|
||||
<Button
|
||||
disabled={ isBusy }
|
||||
icon={ <DoneIcon /> }
|
||||
key='done'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='faucet.buttons.done'
|
||||
defaultMessage='close'
|
||||
/>
|
||||
}
|
||||
onClick={ this.onClose }
|
||||
/>
|
||||
)
|
||||
: [
|
||||
<Button
|
||||
icon={ <CloseIcon /> }
|
||||
key='close'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='faucet.buttons.close'
|
||||
defaultMessage='close'
|
||||
/>
|
||||
}
|
||||
onClick={ this.onClose }
|
||||
/>,
|
||||
<Button
|
||||
disabled={ !canTransact }
|
||||
icon={ <SendIcon /> }
|
||||
key='request'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='faucet.buttons.request'
|
||||
defaultMessage='request'
|
||||
/>
|
||||
}
|
||||
onClick={ this.onExecute }
|
||||
/>
|
||||
];
|
||||
}
|
||||
|
||||
renderSummaryDone () {
|
||||
const { error, responseText, responseTxHash } = this.store;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='faucet.summary.done'
|
||||
defaultMessage='Your Kovan ETH has been requested from the faucet which responded with -'
|
||||
/>
|
||||
{
|
||||
error
|
||||
? (
|
||||
<p>{ error }</p>
|
||||
)
|
||||
: (
|
||||
<p>
|
||||
<span>{ responseText } </span>
|
||||
<a href={ txLink(responseTxHash, false, '42') } target='_blank'>
|
||||
<ShortenedHash data={ responseTxHash } />
|
||||
</a>
|
||||
</p>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderSummaryRequest () {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='faucet.summary.info'
|
||||
defaultMessage='To request a deposit of Kovan ETH to this address, you need to ensure that the address is sms-verified on the mainnet. Once executed the faucet will deposit Kovan ETH into the current account.'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
onClose = () => {
|
||||
this.props.onClose();
|
||||
}
|
||||
|
||||
onExecute = () => {
|
||||
return this.store.makeItRain();
|
||||
}
|
||||
}
|
||||
17
js/src/modals/Faucet/index.js
Normal file
17
js/src/modals/Faucet/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './faucet';
|
||||
126
js/src/modals/Faucet/store.js
Normal file
126
js/src/modals/Faucet/store.js
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { action, computed, observable, transaction } from 'mobx';
|
||||
import apiutil from '~/api/util';
|
||||
|
||||
const ENDPOINT = 'http://faucet.kovan.network/api/';
|
||||
|
||||
export default class Store {
|
||||
@observable addressReceive = null;
|
||||
@observable addressVerified = null;
|
||||
@observable error = null;
|
||||
@observable responseText = null;
|
||||
@observable responseTxHash = null;
|
||||
@observable isBusy = false;
|
||||
@observable isCompleted = false;
|
||||
@observable isDestination = false;
|
||||
@observable isDone = false;
|
||||
|
||||
constructor (netVersion, address) {
|
||||
transaction(() => {
|
||||
this.setDestination(netVersion === '42');
|
||||
|
||||
this.setAddressReceive(address);
|
||||
this.setAddressVerified(address);
|
||||
});
|
||||
}
|
||||
|
||||
@computed get canTransact () {
|
||||
return !this.isBusy && this.addressReceiveValid && this.addressVerifiedValid;
|
||||
}
|
||||
|
||||
@computed get addressReceiveValid () {
|
||||
return apiutil.isAddressValid(this.addressReceive);
|
||||
}
|
||||
|
||||
@computed get addressVerifiedValid () {
|
||||
return apiutil.isAddressValid(this.addressVerified);
|
||||
}
|
||||
|
||||
@action setAddressReceive = (address) => {
|
||||
this.addressReceive = address;
|
||||
}
|
||||
|
||||
@action setAddressVerified = (address) => {
|
||||
this.addressVerified = address;
|
||||
}
|
||||
|
||||
@action setBusy = (isBusy) => {
|
||||
this.isBusy = isBusy;
|
||||
}
|
||||
|
||||
@action setCompleted = (isCompleted) => {
|
||||
transaction(() => {
|
||||
this.setBusy(false);
|
||||
this.isCompleted = isCompleted;
|
||||
});
|
||||
}
|
||||
|
||||
@action setDestination = (isDestination) => {
|
||||
this.isDestination = isDestination;
|
||||
}
|
||||
|
||||
@action setError = (error) => {
|
||||
if (error.indexOf('not certified') !== -1) {
|
||||
this.error = `${error}. Please ensure that this account is sms certified on the mainnet.`;
|
||||
} else {
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
@action setResponse = (response) => {
|
||||
this.responseText = response.result;
|
||||
this.responseTxHash = response.tx;
|
||||
}
|
||||
|
||||
makeItRain = () => {
|
||||
this.setBusy(true);
|
||||
|
||||
const options = {
|
||||
method: 'GET',
|
||||
mode: 'cors'
|
||||
};
|
||||
const url = `${ENDPOINT}${this.addressVerified}`;
|
||||
|
||||
return fetch(url, options)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return response.json();
|
||||
})
|
||||
.catch(() => {
|
||||
return null;
|
||||
})
|
||||
.then((response) => {
|
||||
transaction(() => {
|
||||
if (!response || response.error) {
|
||||
this.setError(
|
||||
response
|
||||
? response.error
|
||||
: 'Unable to complete request to the faucet, the server may be unavailable. Please try again later.'
|
||||
);
|
||||
} else {
|
||||
this.setResponse(response);
|
||||
}
|
||||
|
||||
this.setCompleted(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -401,6 +401,7 @@ class WalletSettings extends Component {
|
||||
const cancelBtn = (
|
||||
<Button
|
||||
icon={ <CancelIcon /> }
|
||||
key='cancelBtn'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='walletSettings.buttons.cancel'
|
||||
@@ -414,6 +415,7 @@ class WalletSettings extends Component {
|
||||
const closeBtn = (
|
||||
<Button
|
||||
icon={ <CancelIcon /> }
|
||||
key='closeBtn'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='walletSettings.buttons.close'
|
||||
@@ -427,6 +429,7 @@ class WalletSettings extends Component {
|
||||
const sendingBtn = (
|
||||
<Button
|
||||
icon={ <DoneIcon /> }
|
||||
key='sendingBtn'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='walletSettings.buttons.sending'
|
||||
@@ -440,6 +443,7 @@ class WalletSettings extends Component {
|
||||
const nextBtn = (
|
||||
<Button
|
||||
icon={ <NextIcon /> }
|
||||
key='nextBtn'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='walletSettings.buttons.next'
|
||||
@@ -454,6 +458,7 @@ class WalletSettings extends Component {
|
||||
const sendBtn = (
|
||||
<Button
|
||||
icon={ <NextIcon /> }
|
||||
key='sendBtn'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='walletSettings.buttons.send'
|
||||
|
||||
@@ -24,6 +24,7 @@ export DeleteAccount from './DeleteAccount';
|
||||
export DeployContract from './DeployContract';
|
||||
export EditMeta from './EditMeta';
|
||||
export ExecuteContract from './ExecuteContract';
|
||||
export Faucet from './Faucet';
|
||||
export FirstRun from './FirstRun';
|
||||
export LoadContract from './LoadContract';
|
||||
export PasswordManager from './PasswordManager';
|
||||
|
||||
Reference in New Issue
Block a user