Dapps use defaultAccount instead of own selectors (#4386)
* Remove account selection from GitHubHint * Fix naming * Update to match BasicCoin * BasicCoin defaultAddress * typo * method registry without selector * Update after manual tests * IdentityIcon for localtx * Fix non-secure personal subscriptions * Query defaultAccount for non-secure apps on send
This commit is contained in:
parent
3af45c6ad9
commit
acf41d6f27
@ -54,15 +54,21 @@ export default class Personal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_accountsInfo = () => {
|
_accountsInfo = () => {
|
||||||
return Promise
|
return this._api.parity
|
||||||
.all([
|
.accountsInfo()
|
||||||
this._api.parity.accountsInfo(),
|
.then((info) => {
|
||||||
this._api.parity.allAccountsInfo()
|
|
||||||
])
|
|
||||||
.then(([info, allInfo]) => {
|
|
||||||
this._updateSubscriptions('parity_accountsInfo', null, info);
|
this._updateSubscriptions('parity_accountsInfo', null, info);
|
||||||
|
|
||||||
|
return this._api.parity
|
||||||
|
.allAccountsInfo()
|
||||||
|
.catch(() => {
|
||||||
|
// NOTE: This fails on non-secure APIs, swallow error
|
||||||
|
return {};
|
||||||
|
})
|
||||||
|
.then((allInfo) => {
|
||||||
this._updateSubscriptions('parity_allAccountsInfo', null, allInfo);
|
this._updateSubscriptions('parity_allAccountsInfo', null, allInfo);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_loggingSubscribe () {
|
_loggingSubscribe () {
|
||||||
|
@ -45,7 +45,7 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.attachInstance();
|
return this.attachInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -80,12 +80,12 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attachInstance () {
|
attachInstance () {
|
||||||
Promise
|
return Promise
|
||||||
.all([
|
.all([
|
||||||
attachInstances(),
|
api.parity.accountsInfo(),
|
||||||
api.parity.accountsInfo()
|
attachInstances()
|
||||||
])
|
])
|
||||||
.then(([{ managerInstance, registryInstance, tokenregInstance }, accountsInfo]) => {
|
.then(([accountsInfo, { managerInstance, registryInstance, tokenregInstance }]) => {
|
||||||
accountsInfo = accountsInfo || {};
|
accountsInfo = accountsInfo || {};
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
import { api } from '../../parity';
|
import { api } from '../../parity';
|
||||||
import AddressSelect from '../../AddressSelect';
|
|
||||||
import Container from '../../Container';
|
import Container from '../../Container';
|
||||||
import styles from './deployment.css';
|
import styles from './deployment.css';
|
||||||
|
|
||||||
@ -122,36 +121,13 @@ export default class Deployment extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderForm () {
|
renderForm () {
|
||||||
const { accounts } = this.context;
|
|
||||||
const { baseText, name, nameError, tla, tlaError, totalSupply, totalSupplyError } = this.state;
|
const { baseText, name, nameError, tla, tlaError, totalSupply, totalSupplyError } = this.state;
|
||||||
const hasError = !!(nameError || tlaError || totalSupplyError);
|
const hasError = !!(nameError || tlaError || totalSupplyError);
|
||||||
const error = `${styles.input} ${styles.error}`;
|
const error = `${styles.input} ${styles.error}`;
|
||||||
const addresses = Object.keys(accounts);
|
|
||||||
|
|
||||||
// <div className={ styles.input }>
|
|
||||||
// <label>global registration</label>
|
|
||||||
// <select onChange={ this.onChangeRegistrar }>
|
|
||||||
// <option value='no'>No, only for me</option>
|
|
||||||
// <option value='yes'>Yes, for everybody</option>
|
|
||||||
// </select>
|
|
||||||
// <div className={ styles.hint }>
|
|
||||||
// register on network (fee: { globalFeeText }ETH)
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<div className={ styles.form }>
|
<div className={ styles.form }>
|
||||||
<div className={ styles.input }>
|
|
||||||
<label>deployment account</label>
|
|
||||||
<AddressSelect
|
|
||||||
addresses={ addresses }
|
|
||||||
onChange={ this.onChangeFrom }
|
|
||||||
/>
|
|
||||||
<div className={ styles.hint }>
|
|
||||||
the owner account to deploy from
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className={ nameError ? error : styles.input }>
|
<div className={ nameError ? error : styles.input }>
|
||||||
<label>token name</label>
|
<label>token name</label>
|
||||||
<input
|
<input
|
||||||
@ -206,12 +182,6 @@ export default class Deployment extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeFrom = (event) => {
|
|
||||||
const fromAddress = event.target.value;
|
|
||||||
|
|
||||||
this.setState({ fromAddress });
|
|
||||||
}
|
|
||||||
|
|
||||||
onChangeName = (event) => {
|
onChangeName = (event) => {
|
||||||
const name = event.target.value;
|
const name = event.target.value;
|
||||||
const nameError = name && (name.length > 2) && (name.length < 32)
|
const nameError = name && (name.length > 2) && (name.length < 32)
|
||||||
@ -271,7 +241,7 @@ export default class Deployment extends Component {
|
|||||||
|
|
||||||
onDeploy = () => {
|
onDeploy = () => {
|
||||||
const { managerInstance, registryInstance, tokenregInstance } = this.context;
|
const { managerInstance, registryInstance, tokenregInstance } = this.context;
|
||||||
const { base, deployBusy, fromAddress, globalReg, globalFee, name, nameError, tla, tlaError, totalSupply, totalSupplyError } = this.state;
|
const { base, deployBusy, globalReg, globalFee, name, nameError, tla, tlaError, totalSupply, totalSupplyError } = this.state;
|
||||||
const hasError = !!(nameError || tlaError || totalSupplyError);
|
const hasError = !!(nameError || tlaError || totalSupplyError);
|
||||||
|
|
||||||
if (hasError || deployBusy) {
|
if (hasError || deployBusy) {
|
||||||
@ -281,14 +251,18 @@ export default class Deployment extends Component {
|
|||||||
const tokenreg = (globalReg ? tokenregInstance : registryInstance).address;
|
const tokenreg = (globalReg ? tokenregInstance : registryInstance).address;
|
||||||
const values = [base.mul(totalSupply), tla, name, tokenreg];
|
const values = [base.mul(totalSupply), tla, name, tokenreg];
|
||||||
const options = {
|
const options = {
|
||||||
from: fromAddress,
|
|
||||||
value: globalReg ? globalFee : 0
|
value: globalReg ? globalFee : 0
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setState({ deployBusy: true, deployState: 'Estimating gas for the transaction' });
|
this.setState({ deployBusy: true, deployState: 'Estimating gas for the transaction' });
|
||||||
|
|
||||||
managerInstance
|
return api.parity
|
||||||
.deploy.estimateGas(options, values)
|
.defaultAccount()
|
||||||
|
.then((defaultAddress) => {
|
||||||
|
options.from = defaultAddress;
|
||||||
|
|
||||||
|
return managerInstance.deploy.estimateGas(options, values);
|
||||||
|
})
|
||||||
.then((gas) => {
|
.then((gas) => {
|
||||||
this.setState({ deployState: 'Gas estimated, Posting transaction to the network' });
|
this.setState({ deployState: 'Gas estimated, Posting transaction to the network' });
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ let registryInstance;
|
|||||||
|
|
||||||
const registries = {};
|
const registries = {};
|
||||||
const subscriptions = {};
|
const subscriptions = {};
|
||||||
|
|
||||||
|
let defaultSubscriptionId;
|
||||||
let nextSubscriptionId = 1000;
|
let nextSubscriptionId = 1000;
|
||||||
let isTest = false;
|
let isTest = false;
|
||||||
|
|
||||||
@ -65,6 +67,20 @@ export function unsubscribeEvents (subscriptionId) {
|
|||||||
delete subscriptions[subscriptionId];
|
delete subscriptions[subscriptionId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function subscribeDefaultAddress (callback) {
|
||||||
|
return api
|
||||||
|
.subscribe('parity_defaultAccount', callback)
|
||||||
|
.then((subscriptionId) => {
|
||||||
|
defaultSubscriptionId = subscriptionId;
|
||||||
|
|
||||||
|
return defaultSubscriptionId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unsubscribeDefaultAddress () {
|
||||||
|
return api.unsubscribe(defaultSubscriptionId);
|
||||||
|
}
|
||||||
|
|
||||||
function pollEvents () {
|
function pollEvents () {
|
||||||
const loop = Object.values(subscriptions);
|
const loop = Object.values(subscriptions);
|
||||||
const timeout = () => setTimeout(pollEvents, 1000);
|
const timeout = () => setTimeout(pollEvents, 1000);
|
||||||
|
@ -17,10 +17,9 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { api } from '../parity';
|
import { api } from '../parity';
|
||||||
import { attachInterface } from '../services';
|
import { attachInterface, subscribeDefaultAddress, unsubscribeDefaultAddress } from '../services';
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
import Events from '../Events';
|
import Events from '../Events';
|
||||||
import IdentityIcon from '../IdentityIcon';
|
|
||||||
import Loading from '../Loading';
|
import Loading from '../Loading';
|
||||||
|
|
||||||
import styles from './application.css';
|
import styles from './application.css';
|
||||||
@ -32,7 +31,7 @@ let nextEventId = 0;
|
|||||||
|
|
||||||
export default class Application extends Component {
|
export default class Application extends Component {
|
||||||
state = {
|
state = {
|
||||||
fromAddress: null,
|
defaultAddress: null,
|
||||||
loading: true,
|
loading: true,
|
||||||
url: '',
|
url: '',
|
||||||
urlError: null,
|
urlError: null,
|
||||||
@ -47,19 +46,32 @@ export default class Application extends Component {
|
|||||||
registerType: 'file',
|
registerType: 'file',
|
||||||
repo: '',
|
repo: '',
|
||||||
repoError: null,
|
repoError: null,
|
||||||
|
subscriptionId: null,
|
||||||
events: {},
|
events: {},
|
||||||
eventIds: []
|
eventIds: []
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
attachInterface()
|
return Promise
|
||||||
.then((state) => {
|
.all([
|
||||||
this.setState(state, () => {
|
attachInterface(),
|
||||||
this.setState({ loading: false });
|
subscribeDefaultAddress((error, defaultAddress) => {
|
||||||
});
|
if (!error) {
|
||||||
|
this.setState({ defaultAddress });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
])
|
||||||
|
.then(([state]) => {
|
||||||
|
this.setState(Object.assign({}, state, {
|
||||||
|
loading: false
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
return unsubscribeDefaultAddress();
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { loading } = this.state;
|
const { loading } = this.state;
|
||||||
|
|
||||||
@ -75,12 +87,14 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderPage () {
|
renderPage () {
|
||||||
const { fromAddress, registerBusy, url, urlError, contentHash, contentHashError, contentHashOwner, commit, commitError, registerType, repo, repoError } = this.state;
|
const { defaultAddress, registerBusy, url, urlError, contentHash, contentHashError, contentHashOwner, commit, commitError, registerType, repo, repoError } = this.state;
|
||||||
|
|
||||||
let hashClass = null;
|
let hashClass = null;
|
||||||
|
|
||||||
if (contentHashError) {
|
if (contentHashError) {
|
||||||
hashClass = contentHashOwner !== fromAddress ? styles.hashError : styles.hashWarning;
|
hashClass = contentHashOwner !== defaultAddress
|
||||||
|
? styles.hashError
|
||||||
|
: styles.hashWarning;
|
||||||
} else if (contentHash) {
|
} else if (contentHash) {
|
||||||
hashClass = styles.hashOk;
|
hashClass = styles.hashOk;
|
||||||
}
|
}
|
||||||
@ -166,20 +180,13 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderButtons () {
|
renderButtons () {
|
||||||
const { accounts, fromAddress, urlError, repoError, commitError, contentHashError, contentHashOwner } = this.state;
|
const { defaultAddress, urlError, repoError, commitError, contentHashError, contentHashOwner } = this.state;
|
||||||
const account = accounts[fromAddress];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.buttons }>
|
<div className={ styles.buttons }>
|
||||||
<div className={ styles.addressSelect }>
|
|
||||||
<Button invert onClick={ this.onSelectFromAddress }>
|
|
||||||
<IdentityIcon address={ account.address } />
|
|
||||||
<div>{ account.name || account.address }</div>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<Button
|
<Button
|
||||||
onClick={ this.onClickRegister }
|
onClick={ this.onClickRegister }
|
||||||
disabled={ (contentHashError && contentHashOwner !== fromAddress) || urlError || repoError || commitError }
|
disabled={ (contentHashError && contentHashOwner !== defaultAddress) || urlError || repoError || commitError }
|
||||||
>register url</Button>
|
>register url</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -294,11 +301,11 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onClickRegister = () => {
|
onClickRegister = () => {
|
||||||
const { commit, commitError, contentHashError, contentHashOwner, fromAddress, url, urlError, registerType, repo, repoError } = this.state;
|
const { defaultAddress, commit, commitError, contentHashError, contentHashOwner, url, urlError, registerType, repo, repoError } = this.state;
|
||||||
|
|
||||||
// TODO: No errors are currently set, validation to be expanded and added for each
|
// TODO: No errors are currently set, validation to be expanded and added for each
|
||||||
// field (query is fast to pick up the issues, so not burning atm)
|
// field (query is fast to pick up the issues, so not burning atm)
|
||||||
if ((contentHashError && contentHashOwner !== fromAddress) || repoError || urlError || commitError) {
|
if ((contentHashError && contentHashOwner !== defaultAddress) || repoError || urlError || commitError) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,13 +375,15 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerContent (contentRepo, contentCommit) {
|
registerContent (contentRepo, contentCommit) {
|
||||||
const { contentHash, fromAddress, instance } = this.state;
|
const { defaultAddress, contentHash, instance } = this.state;
|
||||||
|
|
||||||
contentCommit = contentCommit.substr(0, 2) === '0x' ? contentCommit : `0x${contentCommit}`;
|
contentCommit = contentCommit.substr(0, 2) === '0x'
|
||||||
|
? contentCommit
|
||||||
|
: `0x${contentCommit}`;
|
||||||
|
|
||||||
const eventId = nextEventId++;
|
const eventId = nextEventId++;
|
||||||
const values = [contentHash, contentRepo, contentCommit];
|
const values = [contentHash, contentRepo, contentCommit];
|
||||||
const options = { from: fromAddress };
|
const options = { from: defaultAddress };
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
eventIds: [eventId].concat(this.state.eventIds),
|
eventIds: [eventId].concat(this.state.eventIds),
|
||||||
@ -383,7 +392,7 @@ export default class Application extends Component {
|
|||||||
contentHash,
|
contentHash,
|
||||||
contentRepo,
|
contentRepo,
|
||||||
contentCommit,
|
contentCommit,
|
||||||
fromAddress,
|
defaultAddress,
|
||||||
registerBusy: true,
|
registerBusy: true,
|
||||||
registerState: 'Estimating gas for the transaction',
|
registerState: 'Estimating gas for the transaction',
|
||||||
timestamp: new Date()
|
timestamp: new Date()
|
||||||
@ -421,11 +430,11 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerUrl (contentUrl) {
|
registerUrl (contentUrl) {
|
||||||
const { contentHash, fromAddress, instance } = this.state;
|
const { contentHash, defaultAddress, instance } = this.state;
|
||||||
|
|
||||||
const eventId = nextEventId++;
|
const eventId = nextEventId++;
|
||||||
const values = [contentHash, contentUrl];
|
const values = [contentHash, contentUrl];
|
||||||
const options = { from: fromAddress };
|
const options = { from: defaultAddress };
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
eventIds: [eventId].concat(this.state.eventIds),
|
eventIds: [eventId].concat(this.state.eventIds),
|
||||||
@ -433,7 +442,7 @@ export default class Application extends Component {
|
|||||||
[eventId]: {
|
[eventId]: {
|
||||||
contentHash,
|
contentHash,
|
||||||
contentUrl,
|
contentUrl,
|
||||||
fromAddress,
|
defaultAddress,
|
||||||
registerBusy: true,
|
registerBusy: true,
|
||||||
registerState: 'Estimating gas for the transaction',
|
registerState: 'Estimating gas for the transaction',
|
||||||
timestamp: new Date()
|
timestamp: new Date()
|
||||||
@ -470,25 +479,6 @@ export default class Application extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectFromAddress = () => {
|
|
||||||
const { accounts, fromAddress } = this.state;
|
|
||||||
const addresses = Object.keys(accounts);
|
|
||||||
let index = 0;
|
|
||||||
|
|
||||||
addresses.forEach((address, _index) => {
|
|
||||||
if (address === fromAddress) {
|
|
||||||
index = _index;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
index++;
|
|
||||||
if (index >= addresses.length) {
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({ fromAddress: addresses[index] });
|
|
||||||
}
|
|
||||||
|
|
||||||
lookupHash (url) {
|
lookupHash (url) {
|
||||||
const { instance } = this.state;
|
const { instance } = this.state;
|
||||||
|
|
||||||
|
@ -17,48 +17,44 @@
|
|||||||
import * as abis from '~/contracts/abi';
|
import * as abis from '~/contracts/abi';
|
||||||
import { api } from './parity';
|
import { api } from './parity';
|
||||||
|
|
||||||
|
let defaultSubscriptionId;
|
||||||
|
|
||||||
export function attachInterface () {
|
export function attachInterface () {
|
||||||
return api.parity
|
return api.parity
|
||||||
.registryAddress()
|
.registryAddress()
|
||||||
.then((registryAddress) => {
|
.then((registryAddress) => {
|
||||||
console.log(`the registry was found at ${registryAddress}`);
|
console.log(`the registry was found at ${registryAddress}`);
|
||||||
|
|
||||||
const registry = api.newContract(abis.registry, registryAddress).instance;
|
return api
|
||||||
|
.newContract(abis.registry, registryAddress).instance
|
||||||
return Promise
|
.getAddress.call({}, [api.util.sha3('githubhint'), 'A']);
|
||||||
.all([
|
|
||||||
registry.getAddress.call({}, [api.util.sha3('githubhint'), 'A']),
|
|
||||||
api.parity.accountsInfo()
|
|
||||||
]);
|
|
||||||
})
|
})
|
||||||
.then(([address, accountsInfo]) => {
|
.then((address) => {
|
||||||
console.log(`githubhint was found at ${address}`);
|
console.log(`githubhint was found at ${address}`);
|
||||||
|
|
||||||
const contract = api.newContract(abis.githubhint, address);
|
const contract = api.newContract(abis.githubhint, address);
|
||||||
const accounts = Object
|
|
||||||
.keys(accountsInfo)
|
|
||||||
.reduce((obj, address) => {
|
|
||||||
const account = accountsInfo[address];
|
|
||||||
|
|
||||||
return Object.assign(obj, {
|
|
||||||
[address]: {
|
|
||||||
address,
|
|
||||||
name: account.name
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, {});
|
|
||||||
const fromAddress = Object.keys(accounts)[0];
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
accounts,
|
|
||||||
address,
|
address,
|
||||||
accountsInfo,
|
|
||||||
contract,
|
contract,
|
||||||
instance: contract.instance,
|
instance: contract.instance
|
||||||
fromAddress
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('attachInterface', error);
|
console.error('attachInterface', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function subscribeDefaultAddress (callback) {
|
||||||
|
return api
|
||||||
|
.subscribe('parity_defaultAccount', callback)
|
||||||
|
.then((subscriptionId) => {
|
||||||
|
defaultSubscriptionId = subscriptionId;
|
||||||
|
|
||||||
|
return defaultSubscriptionId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unsubscribeDefaultAddress () {
|
||||||
|
return api.unsubscribe(defaultSubscriptionId);
|
||||||
|
}
|
||||||
|
@ -22,7 +22,7 @@ import { api } from '../parity';
|
|||||||
|
|
||||||
import styles from './transaction.css';
|
import styles from './transaction.css';
|
||||||
|
|
||||||
import IdentityIcon from '../../githubhint/IdentityIcon';
|
import IdentityIcon from '../IdentityIcon';
|
||||||
|
|
||||||
class BaseTransaction extends Component {
|
class BaseTransaction extends Component {
|
||||||
shortHash (hash) {
|
shortHash (hash) {
|
||||||
|
@ -30,7 +30,6 @@ export default class Application extends Component {
|
|||||||
state = {
|
state = {
|
||||||
accounts: {},
|
accounts: {},
|
||||||
address: null,
|
address: null,
|
||||||
fromAddress: null,
|
|
||||||
accountsInfo: {},
|
accountsInfo: {},
|
||||||
blockNumber: new BigNumber(0),
|
blockNumber: new BigNumber(0),
|
||||||
contract: null,
|
contract: null,
|
||||||
@ -41,11 +40,9 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
attachInterface()
|
return attachInterface()
|
||||||
.then((state) => {
|
.then((state) => {
|
||||||
this.setState(state, () => {
|
this.setState(Object.assign({}, state, { loading: false }));
|
||||||
this.setState({ loading: false });
|
|
||||||
});
|
|
||||||
|
|
||||||
return attachBlockNumber(state.instance, (state) => {
|
return attachBlockNumber(state.instance, (state) => {
|
||||||
this.setState(state);
|
this.setState(state);
|
||||||
@ -86,17 +83,14 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderImport () {
|
renderImport () {
|
||||||
const { accounts, fromAddress, instance, showImport } = this.state;
|
const { instance, showImport } = this.state;
|
||||||
|
|
||||||
if (showImport) {
|
if (showImport) {
|
||||||
return (
|
return (
|
||||||
<Import
|
<Import
|
||||||
accounts={ accounts }
|
|
||||||
fromAddress={ fromAddress }
|
|
||||||
instance={ instance }
|
instance={ instance }
|
||||||
visible={ showImport }
|
visible={ showImport }
|
||||||
onClose={ this.toggleImport }
|
onClose={ this.toggleImport }
|
||||||
onSetFromAddress={ this.setFromAddress }
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -124,10 +118,4 @@ export default class Application extends Component {
|
|||||||
showImport: !this.state.showImport
|
showImport: !this.state.showImport
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setFromAddress = (fromAddress) => {
|
|
||||||
this.setState({
|
|
||||||
fromAddress
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,14 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
import { api } from '../parity';
|
import { api } from '../parity';
|
||||||
import { callRegister, postRegister } from '../services';
|
import { callRegister, postRegister } from '../services';
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
import IdentityIcon from '../IdentityIcon';
|
|
||||||
|
|
||||||
import styles from './import.css';
|
import styles from './import.css';
|
||||||
|
|
||||||
export default class Import extends Component {
|
export default class Import extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
accounts: PropTypes.object.isRequired,
|
|
||||||
fromAddress: PropTypes.string.isRequired,
|
|
||||||
instance: PropTypes.object.isRequired,
|
instance: PropTypes.object.isRequired,
|
||||||
visible: PropTypes.bool.isRequired,
|
visible: PropTypes.bool.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired
|
||||||
onSetFromAddress: PropTypes.func.isRequired
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -83,21 +79,12 @@ export default class Import extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderRegister () {
|
renderRegister () {
|
||||||
const { accounts, fromAddress } = this.props;
|
|
||||||
|
|
||||||
const account = accounts[fromAddress];
|
|
||||||
const count = this.countFunctions();
|
const count = this.countFunctions();
|
||||||
let buttons = null;
|
let buttons = null;
|
||||||
|
|
||||||
if (count) {
|
if (count) {
|
||||||
buttons = (
|
buttons = (
|
||||||
<div className={ styles.buttonrow }>
|
<div className={ styles.buttonrow }>
|
||||||
<div className={ styles.addressSelect }>
|
|
||||||
<Button invert onClick={ this.onSelectFromAddress }>
|
|
||||||
<IdentityIcon address={ account.address } />
|
|
||||||
<div>{ account.name || account.address }</div>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<Button onClick={ this.onRegister }>
|
<Button onClick={ this.onRegister }>
|
||||||
register functions
|
register functions
|
||||||
</Button>
|
</Button>
|
||||||
@ -197,15 +184,15 @@ export default class Import extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onRegister = () => {
|
onRegister = () => {
|
||||||
const { instance, fromAddress, onClose } = this.props;
|
const { instance, onClose } = this.props;
|
||||||
const { functions, fnstate } = this.state;
|
const { functions, fnstate } = this.state;
|
||||||
|
|
||||||
Promise
|
return Promise
|
||||||
.all(
|
.all(
|
||||||
functions
|
functions
|
||||||
.filter((fn) => !fn.constant)
|
.filter((fn) => !fn.constant)
|
||||||
.filter((fn) => fnstate[fn.signature] === 'fntodo')
|
.filter((fn) => fnstate[fn.signature] === 'fntodo')
|
||||||
.map((fn) => postRegister(instance, fn.id, { from: fromAddress }))
|
.map((fn) => postRegister(instance, fn.id, {}))
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
onClose();
|
onClose();
|
||||||
@ -214,23 +201,4 @@ export default class Import extends Component {
|
|||||||
console.error('onRegister', error);
|
console.error('onRegister', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectFromAddress = () => {
|
|
||||||
const { accounts, fromAddress, onSetFromAddress } = this.props;
|
|
||||||
const addresses = Object.keys(accounts);
|
|
||||||
let index = 0;
|
|
||||||
|
|
||||||
addresses.forEach((address, _index) => {
|
|
||||||
if (address === fromAddress) {
|
|
||||||
index = _index;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
index++;
|
|
||||||
if (index >= addresses.length) {
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
onSetFromAddress(addresses[index]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -166,8 +166,13 @@ export function callRegister (instance, id, options = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function postRegister (instance, id, options = {}) {
|
export function postRegister (instance, id, options = {}) {
|
||||||
return instance.register
|
return api.parity
|
||||||
.estimateGas(options, [id])
|
.defaultAccount()
|
||||||
|
.then((defaultAddress) => {
|
||||||
|
options.from = defaultAddress;
|
||||||
|
|
||||||
|
return instance.register.estimateGas(options, [id]);
|
||||||
|
})
|
||||||
.then((gas) => {
|
.then((gas) => {
|
||||||
options.gas = gas.mul(1.2).toFixed(0);
|
options.gas = gas.mul(1.2).toFixed(0);
|
||||||
console.log('postRegister', `gas estimated at ${gas.toFormat(0)}, setting to ${gas.mul(1.2).toFormat(0)}`);
|
console.log('postRegister', `gas estimated at ${gas.toFormat(0)}, setting to ${gas.mul(1.2).toFormat(0)}`);
|
||||||
|
Loading…
Reference in New Issue
Block a user