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:
committed by
Gav Wood
parent
88c0329a31
commit
fd41a10319
@@ -26,8 +26,8 @@ import TextFieldUnderline from 'material-ui/TextField/TextFieldUnderline';
|
||||
import AccountCard from '~/ui/AccountCard';
|
||||
import InputAddress from '~/ui/Form/InputAddress';
|
||||
import Portal from '~/ui/Portal';
|
||||
import { validateAddress } from '~/util/validation';
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
import { validateAddress } from '~/util/validation';
|
||||
|
||||
import AddressSelectStore from './addressSelectStore';
|
||||
import styles from './addressSelect.css';
|
||||
@@ -40,6 +40,7 @@ let currentId = 1;
|
||||
@observer
|
||||
class AddressSelect extends Component {
|
||||
static contextTypes = {
|
||||
intl: React.PropTypes.object.isRequired,
|
||||
api: PropTypes.object.isRequired,
|
||||
muiTheme: PropTypes.object.isRequired
|
||||
};
|
||||
@@ -55,7 +56,6 @@ class AddressSelect extends Component {
|
||||
contacts: PropTypes.object,
|
||||
contracts: PropTypes.object,
|
||||
tokens: PropTypes.object,
|
||||
wallets: PropTypes.object,
|
||||
|
||||
// Optional props
|
||||
allowInput: PropTypes.bool,
|
||||
@@ -160,6 +160,12 @@ class AddressSelect extends Component {
|
||||
}
|
||||
|
||||
const id = `addressSelect_${++currentId}`;
|
||||
const ilHint = typeof hint === 'string' || !(hint && hint.props)
|
||||
? (hint || '')
|
||||
: this.context.intl.formatMessage(
|
||||
hint.props,
|
||||
hint.props.values || {}
|
||||
);
|
||||
|
||||
return (
|
||||
<Portal
|
||||
@@ -174,7 +180,7 @@ class AddressSelect extends Component {
|
||||
<input
|
||||
id={ id }
|
||||
className={ styles.input }
|
||||
placeholder={ hint }
|
||||
placeholder={ ilHint }
|
||||
|
||||
onBlur={ this.handleInputBlur }
|
||||
onFocus={ this.handleInputFocus }
|
||||
|
||||
@@ -78,14 +78,13 @@ export default class AddressSelectStore {
|
||||
}
|
||||
|
||||
@action setValues (props) {
|
||||
const { accounts = {}, contracts = {}, contacts = {}, wallets = {} } = props;
|
||||
const { accounts = {}, contracts = {}, contacts = {} } = props;
|
||||
|
||||
const accountsN = Object.keys(accounts).length;
|
||||
const contractsN = Object.keys(contracts).length;
|
||||
const contactsN = Object.keys(contacts).length;
|
||||
const walletsN = Object.keys(wallets).length;
|
||||
|
||||
if (accountsN + contractsN + contactsN + walletsN === 0) {
|
||||
if (accountsN + contractsN + contactsN === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -98,10 +97,7 @@ export default class AddressSelectStore {
|
||||
defaultMessage='accounts'
|
||||
/>
|
||||
),
|
||||
values: [].concat(
|
||||
Object.values(wallets),
|
||||
Object.values(accounts)
|
||||
)
|
||||
values: Object.values(accounts)
|
||||
},
|
||||
{
|
||||
key: 'contacts',
|
||||
|
||||
@@ -51,6 +51,7 @@ export default class Input extends Component {
|
||||
PropTypes.string,
|
||||
PropTypes.bool
|
||||
]),
|
||||
autoFocus: PropTypes.bool,
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
@@ -112,7 +113,7 @@ export default class Input extends Component {
|
||||
|
||||
render () {
|
||||
const { value } = this.state;
|
||||
const { children, className, hideUnderline, disabled, error, focused, label } = this.props;
|
||||
const { autoFocus, children, className, hideUnderline, disabled, error, focused, label } = this.props;
|
||||
const { hint, onClick, onFocus, multiLine, rows, type, min, max, style, tabIndex } = this.props;
|
||||
|
||||
const readOnly = this.props.readOnly || disabled;
|
||||
@@ -138,6 +139,7 @@ export default class Input extends Component {
|
||||
{ this.renderCopyButton() }
|
||||
<TextField
|
||||
autoComplete='off'
|
||||
autoFocus={ autoFocus }
|
||||
className={ className }
|
||||
errorText={ error }
|
||||
floatingLabelFixed
|
||||
|
||||
@@ -25,7 +25,6 @@ class InputAddressSelect extends Component {
|
||||
accounts: PropTypes.object.isRequired,
|
||||
contacts: PropTypes.object.isRequired,
|
||||
contracts: PropTypes.object.isRequired,
|
||||
wallets: PropTypes.object.isRequired,
|
||||
error: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
hint: PropTypes.string,
|
||||
@@ -34,7 +33,7 @@ class InputAddressSelect extends Component {
|
||||
};
|
||||
|
||||
render () {
|
||||
const { accounts, contacts, contracts, wallets, label, hint, error, value, onChange } = this.props;
|
||||
const { accounts, contacts, contracts, label, hint, error, value, onChange } = this.props;
|
||||
|
||||
return (
|
||||
<AddressSelect
|
||||
@@ -42,7 +41,6 @@ class InputAddressSelect extends Component {
|
||||
accounts={ accounts }
|
||||
contacts={ contacts }
|
||||
contracts={ contracts }
|
||||
wallets={ wallets }
|
||||
error={ error }
|
||||
label={ label }
|
||||
hint={ hint }
|
||||
@@ -53,13 +51,12 @@ class InputAddressSelect extends Component {
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts, contacts, contracts, wallets } = state.personal;
|
||||
const { accounts, contacts, contracts } = state.personal;
|
||||
|
||||
return {
|
||||
accounts,
|
||||
contacts,
|
||||
contracts,
|
||||
wallets
|
||||
contracts
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -67,15 +67,7 @@ export default class TypedInput extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { param } = this.props;
|
||||
|
||||
if (typeof param === 'string') {
|
||||
const parsedParam = parseAbiType(param);
|
||||
|
||||
if (parsedParam) {
|
||||
return this.renderParam(parsedParam);
|
||||
}
|
||||
}
|
||||
const param = this.getParam();
|
||||
|
||||
if (param) {
|
||||
return this.renderParam(param);
|
||||
@@ -234,7 +226,8 @@ export default class TypedInput extends Component {
|
||||
}
|
||||
|
||||
renderInteger (value = this.props.value, onChange = this.onChange) {
|
||||
const { label, error, param, hint, min, max } = this.props;
|
||||
const { label, error, hint, min, max } = this.props;
|
||||
const param = this.getParam();
|
||||
|
||||
const realValue = value && typeof value.toNumber === 'function'
|
||||
? value.toNumber()
|
||||
@@ -263,7 +256,8 @@ export default class TypedInput extends Component {
|
||||
* @see https://github.com/facebook/react/issues/1549
|
||||
*/
|
||||
renderFloat (value = this.props.value, onChange = this.onChange) {
|
||||
const { label, error, param, hint, min, max } = this.props;
|
||||
const { label, error, hint, min, max } = this.props;
|
||||
const param = this.getParam();
|
||||
|
||||
const realValue = value && typeof value.toNumber === 'function'
|
||||
? value.toNumber()
|
||||
@@ -379,7 +373,9 @@ export default class TypedInput extends Component {
|
||||
}
|
||||
|
||||
onAddField = () => {
|
||||
const { value, onChange, param } = this.props;
|
||||
const { value, onChange } = this.props;
|
||||
const param = this.getParam();
|
||||
|
||||
const newValues = [].concat(value, param.subtype.default);
|
||||
|
||||
onChange(newValues);
|
||||
@@ -392,4 +388,14 @@ export default class TypedInput extends Component {
|
||||
onChange(newValues);
|
||||
}
|
||||
|
||||
getParam = () => {
|
||||
const { param } = this.props;
|
||||
|
||||
if (typeof param === 'string') {
|
||||
return parseAbiType(param);
|
||||
}
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -118,6 +118,15 @@ export default class MethodDecodingStore {
|
||||
return Promise.resolve(result);
|
||||
}
|
||||
|
||||
try {
|
||||
const { signature } = this.api.util.decodeCallData(input);
|
||||
|
||||
if (signature === CONTRACT_CREATE || transaction.creates) {
|
||||
result.contract = true;
|
||||
return Promise.resolve({ ...result, deploy: true });
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
return this
|
||||
.isContract(contractAddress || transaction.creates)
|
||||
.then((isContract) => {
|
||||
@@ -132,7 +141,7 @@ export default class MethodDecodingStore {
|
||||
result.params = paramdata;
|
||||
|
||||
// Contract deployment
|
||||
if (!signature || signature === CONTRACT_CREATE || transaction.creates) {
|
||||
if (!signature) {
|
||||
return Promise.resolve({ ...result, deploy: true });
|
||||
}
|
||||
|
||||
@@ -192,7 +201,7 @@ export default class MethodDecodingStore {
|
||||
*/
|
||||
isContract (contractAddress) {
|
||||
// If zero address, it isn't a contract
|
||||
if (/^(0x)?0*$/.test(contractAddress)) {
|
||||
if (!contractAddress || /^(0x)?0*$/.test(contractAddress)) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Portal from 'react-portal';
|
||||
import ReactPortal from 'react-portal';
|
||||
import keycode from 'keycode';
|
||||
|
||||
import { CloseIcon } from '~/ui/Icons';
|
||||
@@ -24,7 +24,7 @@ import ParityBackground from '~/ui/ParityBackground';
|
||||
|
||||
import styles from './portal.css';
|
||||
|
||||
export default class Protal extends Component {
|
||||
export default class Portal extends Component {
|
||||
|
||||
static propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
@@ -65,7 +65,7 @@ export default class Protal extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<Portal isOpened onClose={ this.handleClose }>
|
||||
<ReactPortal isOpened onClose={ this.handleClose }>
|
||||
<div
|
||||
className={ classes.join(' ') }
|
||||
onKeyDown={ this.handleKeyDown }
|
||||
@@ -75,7 +75,7 @@ export default class Protal extends Component {
|
||||
{ this.renderCloseIcon() }
|
||||
{ children }
|
||||
</div>
|
||||
</Portal>
|
||||
</ReactPortal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ class TxHash extends Component {
|
||||
const { api } = this.context;
|
||||
const { hash } = this.props;
|
||||
|
||||
if (error) {
|
||||
if (error || !hash || /^(0x)?0*$/.test(hash)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user