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:
@@ -17,10 +17,9 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { api } from '../parity';
|
||||
import { attachInterface } from '../services';
|
||||
import { attachInterface, subscribeDefaultAddress, unsubscribeDefaultAddress } from '../services';
|
||||
import Button from '../Button';
|
||||
import Events from '../Events';
|
||||
import IdentityIcon from '../IdentityIcon';
|
||||
import Loading from '../Loading';
|
||||
|
||||
import styles from './application.css';
|
||||
@@ -32,7 +31,7 @@ let nextEventId = 0;
|
||||
|
||||
export default class Application extends Component {
|
||||
state = {
|
||||
fromAddress: null,
|
||||
defaultAddress: null,
|
||||
loading: true,
|
||||
url: '',
|
||||
urlError: null,
|
||||
@@ -47,19 +46,32 @@ export default class Application extends Component {
|
||||
registerType: 'file',
|
||||
repo: '',
|
||||
repoError: null,
|
||||
subscriptionId: null,
|
||||
events: {},
|
||||
eventIds: []
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
attachInterface()
|
||||
.then((state) => {
|
||||
this.setState(state, () => {
|
||||
this.setState({ loading: false });
|
||||
});
|
||||
return Promise
|
||||
.all([
|
||||
attachInterface(),
|
||||
subscribeDefaultAddress((error, defaultAddress) => {
|
||||
if (!error) {
|
||||
this.setState({ defaultAddress });
|
||||
}
|
||||
})
|
||||
])
|
||||
.then(([state]) => {
|
||||
this.setState(Object.assign({}, state, {
|
||||
loading: false
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
return unsubscribeDefaultAddress();
|
||||
}
|
||||
|
||||
render () {
|
||||
const { loading } = this.state;
|
||||
|
||||
@@ -75,12 +87,14 @@ export default class Application extends Component {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (contentHashError) {
|
||||
hashClass = contentHashOwner !== fromAddress ? styles.hashError : styles.hashWarning;
|
||||
hashClass = contentHashOwner !== defaultAddress
|
||||
? styles.hashError
|
||||
: styles.hashWarning;
|
||||
} else if (contentHash) {
|
||||
hashClass = styles.hashOk;
|
||||
}
|
||||
@@ -166,20 +180,13 @@ export default class Application extends Component {
|
||||
}
|
||||
|
||||
renderButtons () {
|
||||
const { accounts, fromAddress, urlError, repoError, commitError, contentHashError, contentHashOwner } = this.state;
|
||||
const account = accounts[fromAddress];
|
||||
const { defaultAddress, urlError, repoError, commitError, contentHashError, contentHashOwner } = this.state;
|
||||
|
||||
return (
|
||||
<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
|
||||
onClick={ this.onClickRegister }
|
||||
disabled={ (contentHashError && contentHashOwner !== fromAddress) || urlError || repoError || commitError }
|
||||
disabled={ (contentHashError && contentHashOwner !== defaultAddress) || urlError || repoError || commitError }
|
||||
>register url</Button>
|
||||
</div>
|
||||
);
|
||||
@@ -294,11 +301,11 @@ export default class Application extends Component {
|
||||
}
|
||||
|
||||
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
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -368,13 +375,15 @@ export default class Application extends Component {
|
||||
}
|
||||
|
||||
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 values = [contentHash, contentRepo, contentCommit];
|
||||
const options = { from: fromAddress };
|
||||
const options = { from: defaultAddress };
|
||||
|
||||
this.setState({
|
||||
eventIds: [eventId].concat(this.state.eventIds),
|
||||
@@ -383,7 +392,7 @@ export default class Application extends Component {
|
||||
contentHash,
|
||||
contentRepo,
|
||||
contentCommit,
|
||||
fromAddress,
|
||||
defaultAddress,
|
||||
registerBusy: true,
|
||||
registerState: 'Estimating gas for the transaction',
|
||||
timestamp: new Date()
|
||||
@@ -421,11 +430,11 @@ export default class Application extends Component {
|
||||
}
|
||||
|
||||
registerUrl (contentUrl) {
|
||||
const { contentHash, fromAddress, instance } = this.state;
|
||||
const { contentHash, defaultAddress, instance } = this.state;
|
||||
|
||||
const eventId = nextEventId++;
|
||||
const values = [contentHash, contentUrl];
|
||||
const options = { from: fromAddress };
|
||||
const options = { from: defaultAddress };
|
||||
|
||||
this.setState({
|
||||
eventIds: [eventId].concat(this.state.eventIds),
|
||||
@@ -433,7 +442,7 @@ export default class Application extends Component {
|
||||
[eventId]: {
|
||||
contentHash,
|
||||
contentUrl,
|
||||
fromAddress,
|
||||
defaultAddress,
|
||||
registerBusy: true,
|
||||
registerState: 'Estimating gas for the transaction',
|
||||
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) {
|
||||
const { instance } = this.state;
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
.icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// 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 React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { api } from '../parity';
|
||||
import styles from './identityIcon.css';
|
||||
|
||||
export default class IdentityIcon extends Component {
|
||||
static propTypes = {
|
||||
address: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
const { address } = this.props;
|
||||
|
||||
return (
|
||||
<img
|
||||
className={ styles.icon }
|
||||
src={ api.util.createIdentityImg(address, 3) }
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// 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 './identityIcon';
|
||||
@@ -17,48 +17,44 @@
|
||||
import * as abis from '~/contracts/abi';
|
||||
import { api } from './parity';
|
||||
|
||||
let defaultSubscriptionId;
|
||||
|
||||
export function attachInterface () {
|
||||
return api.parity
|
||||
.registryAddress()
|
||||
.then((registryAddress) => {
|
||||
console.log(`the registry was found at ${registryAddress}`);
|
||||
|
||||
const registry = api.newContract(abis.registry, registryAddress).instance;
|
||||
|
||||
return Promise
|
||||
.all([
|
||||
registry.getAddress.call({}, [api.util.sha3('githubhint'), 'A']),
|
||||
api.parity.accountsInfo()
|
||||
]);
|
||||
return api
|
||||
.newContract(abis.registry, registryAddress).instance
|
||||
.getAddress.call({}, [api.util.sha3('githubhint'), 'A']);
|
||||
})
|
||||
.then(([address, accountsInfo]) => {
|
||||
.then((address) => {
|
||||
console.log(`githubhint was found at ${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 {
|
||||
accounts,
|
||||
address,
|
||||
accountsInfo,
|
||||
contract,
|
||||
instance: contract.instance,
|
||||
fromAddress
|
||||
instance: contract.instance
|
||||
};
|
||||
})
|
||||
.catch((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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user