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

@@ -23,6 +23,7 @@ export default class RequestPending extends Component {
static propTypes = {
className: PropTypes.string,
date: PropTypes.instanceOf(Date).isRequired,
focus: PropTypes.bool,
gasLimit: PropTypes.object.isRequired,
id: PropTypes.object.isRequired,
isSending: PropTypes.bool.isRequired,
@@ -38,6 +39,7 @@ export default class RequestPending extends Component {
};
static defaultProps = {
focus: false,
isSending: false
};
@@ -49,7 +51,7 @@ export default class RequestPending extends Component {
};
render () {
const { className, date, gasLimit, id, isSending, isTest, onReject, payload, store } = this.props;
const { className, date, focus, gasLimit, id, isSending, isTest, onReject, payload, store } = this.props;
if (payload.sign) {
const { sign } = payload;
@@ -58,6 +60,7 @@ export default class RequestPending extends Component {
<SignRequest
address={ sign.address }
className={ className }
focus={ focus }
hash={ sign.hash }
id={ id }
isFinished={ false }
@@ -75,6 +78,7 @@ export default class RequestPending extends Component {
<TransactionPending
className={ className }
date={ date }
focus={ focus }
gasLimit={ gasLimit }
id={ id }
isSending={ isSending }

View File

@@ -30,13 +30,19 @@ export default class SignRequest extends Component {
address: PropTypes.string.isRequired,
hash: PropTypes.string.isRequired,
isFinished: PropTypes.bool.isRequired,
isTest: PropTypes.bool.isRequired,
store: PropTypes.object.isRequired,
className: PropTypes.string,
focus: PropTypes.bool,
isSending: PropTypes.bool,
onConfirm: PropTypes.func,
onReject: PropTypes.func,
status: PropTypes.string,
className: PropTypes.string,
isTest: PropTypes.bool.isRequired,
store: PropTypes.object.isRequired
status: PropTypes.string
};
static defaultProps = {
focus: false
};
componentWillMount () {
@@ -81,7 +87,7 @@ export default class SignRequest extends Component {
}
renderActions () {
const { address, isFinished, status } = this.props;
const { address, focus, isFinished, status } = this.props;
if (isFinished) {
if (status === 'confirmed') {
@@ -111,6 +117,7 @@ export default class SignRequest extends Component {
return (
<TransactionPendingForm
address={ address }
focus={ focus }
isSending={ this.props.isSending }
onConfirm={ this.onConfirm }
onReject={ this.onReject }

View File

@@ -35,6 +35,7 @@ export default class TransactionPending extends Component {
static propTypes = {
className: PropTypes.string,
date: PropTypes.instanceOf(Date).isRequired,
focus: PropTypes.bool,
gasLimit: PropTypes.object,
id: PropTypes.object.isRequired,
isSending: PropTypes.bool.isRequired,
@@ -53,6 +54,10 @@ export default class TransactionPending extends Component {
}).isRequired
};
static defaultProps = {
focus: false
};
gasStore = new GasPriceEditor.Store(this.context.api, {
gas: this.props.transaction.gas.toFixed(),
gasLimit: this.props.gasLimit,
@@ -80,7 +85,7 @@ export default class TransactionPending extends Component {
}
renderTransaction () {
const { className, id, isSending, isTest, store, transaction } = this.props;
const { className, focus, id, isSending, isTest, store, transaction } = this.props;
const { totalValue } = this.state;
const { from, value } = transaction;
@@ -100,6 +105,7 @@ export default class TransactionPending extends Component {
value={ value } />
<TransactionPendingForm
address={ from }
focus={ focus }
isSending={ isSending }
onConfirm={ this.onConfirm }
onReject={ this.onReject } />

View File

@@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import RaisedButton from 'material-ui/RaisedButton';
@@ -26,11 +27,16 @@ import styles from './transactionPendingFormConfirm.css';
class TransactionPendingFormConfirm extends Component {
static propTypes = {
accounts: PropTypes.object.isRequired,
account: PropTypes.object.isRequired,
address: PropTypes.string.isRequired,
isSending: PropTypes.bool.isRequired,
onConfirm: PropTypes.func.isRequired
}
onConfirm: PropTypes.func.isRequired,
focus: PropTypes.bool
};
static defaultProps = {
focus: false
};
id = Math.random(); // for tooltip
@@ -40,10 +46,39 @@ class TransactionPendingFormConfirm extends Component {
walletError: null
}
componentDidMount () {
this.focus();
}
componentWillReceiveProps (nextProps) {
if (!this.props.focus && nextProps.focus) {
this.focus(nextProps);
}
}
/**
* Properly focus on the input element when needed.
* This might be fixed some day in MaterialUI with
* an autoFocus prop.
*
* @see https://github.com/callemall/material-ui/issues/5632
*/
focus (props = this.props) {
if (props.focus) {
const textNode = ReactDOM.findDOMNode(this.refs.input);
if (!textNode) {
return;
}
const inputNode = textNode.querySelector('input');
inputNode && inputNode.focus();
}
}
render () {
const { accounts, address, isSending } = this.props;
const { account, address, isSending } = this.props;
const { password, wallet, walletError } = this.state;
const account = accounts[address] || {};
const isExternal = !account.uuid;
const passwordHint = account.meta && account.meta.passwordHint
@@ -72,8 +107,10 @@ class TransactionPendingFormConfirm extends Component {
}
onChange={ this.onModifyPassword }
onKeyDown={ this.onKeyDown }
ref='input'
type='password'
value={ password } />
value={ password }
/>
<div className={ styles.passwordHint }>
{ passwordHint }
</div>
@@ -178,11 +215,14 @@ class TransactionPendingFormConfirm extends Component {
}
}
function mapStateToProps (state) {
const { accounts } = state.personal;
function mapStateToProps (initState, initProps) {
const { accounts } = initState.personal;
const { address } = initProps;
return {
accounts
const account = accounts[address] || {};
return () => {
return { account };
};
}

View File

@@ -28,7 +28,12 @@ export default class TransactionPendingForm extends Component {
isSending: PropTypes.bool.isRequired,
onConfirm: PropTypes.func.isRequired,
onReject: PropTypes.func.isRequired,
className: PropTypes.string
className: PropTypes.string,
focus: PropTypes.bool
};
static defaultProps = {
focus: false
};
state = {
@@ -47,7 +52,7 @@ export default class TransactionPendingForm extends Component {
}
renderForm () {
const { address, isSending, onConfirm, onReject } = this.props;
const { address, focus, isSending, onConfirm, onReject } = this.props;
if (this.state.isRejectOpen) {
return (
@@ -59,8 +64,10 @@ export default class TransactionPendingForm extends Component {
return (
<TransactionPendingFormConfirm
address={ address }
focus={ focus }
isSending={ isSending }
onConfirm={ onConfirm } />
onConfirm={ onConfirm }
/>
);
}

View File

@@ -78,7 +78,7 @@ class Embedded extends Component {
);
}
renderPending = (data) => {
renderPending = (data, index) => {
const { actions, gasLimit, isTest } = this.props;
const { date, id, isSending, payload } = data;
@@ -86,6 +86,7 @@ class Embedded extends Component {
<RequestPending
className={ styles.request }
date={ date }
focus={ index === 0 }
gasLimit={ gasLimit }
id={ id }
isSending={ isSending }

View File

@@ -104,7 +104,7 @@ class RequestsPage extends Component {
);
}
renderPending = (data) => {
renderPending = (data, index) => {
const { actions, gasLimit, isTest } = this.props;
const { date, id, isSending, payload } = data;
@@ -112,6 +112,7 @@ class RequestsPage extends Component {
<RequestPending
className={ styles.request }
date={ date }
focus={ index === 0 }
gasLimit={ gasLimit }
id={ id }
isSending={ isSending }