Make Wallet first-class citizens (#3990)

* Fixed hint in Address Select + Wallet as first-class-citizen

* Separate Owned and not Owned Wallets

* Fix balance not updating

* Fix MethodDecoding for Contract Deployment

* Fix TypedInput params

* Fix Token Transfer for Wallet

* Small change to contracts

* Fix wallets shown twice

* Fix separation of accounts and wallets in Accounts

* Fix linting

* Execute contract methods from Wallet ✓

* Fixing linting

* Wallet as first-class citizen: Part 1 (Manual) #3784

* Lower level wallet transaction convertion

* Fix linting

* Proper autoFocus on right Signer input

* PR Grumble: don't show Wallets in dApps Permissions

* Add postTransaction and gasEstimate wrapper methods

* Extract Wallet postTx and gasEstimate to utils + PATCH api

* Remove invalid test

It's totally valid for input's length not to be a multiple of 32 bytes. EG. for Wallet Contracts

* Merge master

* Fix linting

* Fix merge issue

* Rename Portal

* Rename Protal => Portal (typo)
This commit is contained in:
Nicolas Gotchac
2016-12-30 12:28:12 +01:00
committed by Gav Wood
parent 88c0329a31
commit fd41a10319
46 changed files with 570 additions and 230 deletions

View File

@@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react';
import { omitBy } from 'lodash';
import { Form, TypedInput, Input, AddressSelect, InputAddress } from '~/ui';
@@ -73,6 +74,9 @@ 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>
<AddressSelect
@@ -81,7 +85,7 @@ export default class WalletDetails extends Component {
value={ wallet.account }
error={ errors.account }
onChange={ this.onAccoutChange }
accounts={ accounts }
accounts={ _accounts }
/>
<Input

View File

@@ -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 } from 'lodash';
import { pick, omitBy } from 'lodash';
import { observer } from 'mobx-react';
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
@@ -561,13 +561,19 @@ class DeployContract extends Component {
}
function mapStateToProps (initState, initProps) {
const fromAddresses = Object.keys(initProps.accounts);
const { accounts } = initProps;
// Skip Wallet accounts : they can't create Contracts
const _accounts = omitBy(accounts, (a) => a.wallet);
const fromAddresses = Object.keys(_accounts);
return (state) => {
const balances = pick(state.balances.balances, fromAddresses);
const { gasLimit } = state.nodeStatus;
return {
accounts: _accounts,
balances,
gasLimit
};

View File

@@ -389,6 +389,7 @@ class ExecuteContract extends Component {
const { advancedOptions, amount, func, minBlock, values } = this.state;
const steps = advancedOptions ? STAGES_ADVANCED : STAGES_BASIC;
const finalstep = steps.length - 1;
const options = {
gas: this.gasStore.gas,
gasPrice: this.gasStore.price,

View File

@@ -383,9 +383,7 @@ export default class TransferStore {
const senderBalance = this.balance.tokens.find((b) => tag === b.token.tag);
const format = new BigNumber(senderBalance.token.format || 1);
const available = isWallet
? this.api.util.fromWei(new BigNumber(senderBalance.value))
: (new BigNumber(senderBalance.value)).div(format);
const available = new BigNumber(senderBalance.value).div(format);
let { value, valueError } = this;
let totalEth = gasTotal;
@@ -428,7 +426,6 @@ export default class TransferStore {
send () {
const { options, values } = this._getTransferParams();
options.minBlock = new BigNumber(this.minBlock || 0).gt(0) ? this.minBlock : null;
return this._getTransferMethod().postTransaction(options, values);
@@ -440,16 +437,7 @@ export default class TransferStore {
}
estimateGas () {
if (this.isEth || !this.isWallet) {
return this._estimateGas();
}
return Promise
.all([
this._estimateGas(true),
this._estimateGas()
])
.then((results) => results[0].plus(results[1]));
return this._estimateGas();
}
_getTransferMethod (gas = false, forceToken = false) {

View File

@@ -36,7 +36,7 @@ class WalletSettings extends Component {
};
static propTypes = {
accounts: PropTypes.object.isRequired,
accountsInfo: PropTypes.object.isRequired,
wallet: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
senders: PropTypes.object.isRequired
@@ -113,7 +113,7 @@ class WalletSettings extends Component {
default:
case 'EDIT':
const { wallet, errors } = this.store;
const { accounts, senders } = this.props;
const { accountsInfo, senders } = this.props;
return (
<Form>
@@ -137,7 +137,7 @@ class WalletSettings extends Component {
label='other wallet owners'
value={ wallet.owners.slice() }
onChange={ this.store.onOwnersChange }
accounts={ accounts }
accounts={ accountsInfo }
param='address[]'
/>
@@ -190,7 +190,7 @@ class WalletSettings extends Component {
}
renderChange (change) {
const { accounts } = this.props;
const { accountsInfo } = this.props;
switch (change.type) {
case 'dailylimit':
@@ -229,7 +229,7 @@ class WalletSettings extends Component {
<InputAddress
disabled
value={ change.value }
accounts={ accounts }
accounts={ accountsInfo }
/>
</div>
</div>
@@ -243,7 +243,7 @@ class WalletSettings extends Component {
<InputAddress
disabled
value={ change.value }
accounts={ accounts }
accounts={ accountsInfo }
/>
</div>
</div>
@@ -329,7 +329,7 @@ function mapStateToProps (initState, initProps) {
const senders = pick(accounts, owners);
return () => {
return { accounts: accountsInfo, senders };
return { accountsInfo, senders };
};
}

View File

@@ -28,6 +28,8 @@ const STEPS = {
};
export default class WalletSettingsStore {
accounts = {};
@observable step = null;
@observable requests = [];
@observable deployState = '';