Merge branch 'master' into jg-block-gasLimit
This commit is contained in:
		
						commit
						2de38c9238
					
				@ -86,7 +86,7 @@ impl SecretStore for EthStore {
 | 
				
			|||||||
	fn insert_account(&self, secret: Secret, password: &str) -> Result<Address, Error> {
 | 
						fn insert_account(&self, secret: Secret, password: &str) -> Result<Address, Error> {
 | 
				
			||||||
		let keypair = try!(KeyPair::from_secret(secret).map_err(|_| Error::CreationFailed));
 | 
							let keypair = try!(KeyPair::from_secret(secret).map_err(|_| Error::CreationFailed));
 | 
				
			||||||
		let id: [u8; 16] = Random::random();
 | 
							let id: [u8; 16] = Random::random();
 | 
				
			||||||
		let account = SafeAccount::create(&keypair, id, password, self.iterations, UUID::from(id).into(), "{}".to_owned());
 | 
							let account = SafeAccount::create(&keypair, id, password, self.iterations, "".to_owned(), "{}".to_owned());
 | 
				
			||||||
		let address = account.address.clone();
 | 
							let address = account.address.clone();
 | 
				
			||||||
		try!(self.save(account));
 | 
							try!(self.save(account));
 | 
				
			||||||
		Ok(address)
 | 
							Ok(address)
 | 
				
			||||||
 | 
				
			|||||||
@ -43,6 +43,7 @@
 | 
				
			|||||||
    "test": "mocha 'src/**/*.spec.js'",
 | 
					    "test": "mocha 'src/**/*.spec.js'",
 | 
				
			||||||
    "test:coverage": "istanbul cover _mocha -- 'src/**/*.spec.js'",
 | 
					    "test:coverage": "istanbul cover _mocha -- 'src/**/*.spec.js'",
 | 
				
			||||||
    "test:e2e": "mocha 'src/**/*.e2e.js'",
 | 
					    "test:e2e": "mocha 'src/**/*.e2e.js'",
 | 
				
			||||||
 | 
					    "test:npm": "(cd .npmjs && npm i) && node test/npmLibrary && (rm -rf .npmjs/node_modules)",
 | 
				
			||||||
    "prepush": "npm run lint:cached"
 | 
					    "prepush": "npm run lint:cached"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,7 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "bignumber.js": "^2.3.0",
 | 
					    "bignumber.js": "^2.3.0",
 | 
				
			||||||
    "js-sha3": "^0.5.2"
 | 
					    "js-sha3": "^0.5.2",
 | 
				
			||||||
 | 
					    "node-fetch": "^1.6.3"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -84,7 +84,7 @@ export default class Ws extends JsonRpcBase {
 | 
				
			|||||||
    this._connecting = false;
 | 
					    this._connecting = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this._autoConnect) {
 | 
					    if (this._autoConnect) {
 | 
				
			||||||
      this._connect();
 | 
					      setTimeout(() => this._connect(), 500);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -14,10 +14,22 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'babel-polyfill/dist/polyfill.js';
 | 
				
			||||||
 | 
					import es6Promise from 'es6-promise';
 | 
				
			||||||
 | 
					es6Promise.polyfill();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const isNode = typeof global !== 'undefined' && typeof global !== 'undefined';
 | 
				
			||||||
 | 
					const isBrowser = typeof self !== 'undefined' && typeof self.window !== 'undefined';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (isBrowser) {
 | 
				
			||||||
 | 
					  require('whatwg-fetch');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (isNode) {
 | 
				
			||||||
 | 
					  global.fetch = require('node-fetch');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Abi from './abi';
 | 
					import Abi from './abi';
 | 
				
			||||||
import Api from './api';
 | 
					import Api from './api';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export {
 | 
					module.exports = { Api, Abi };
 | 
				
			||||||
  Abi,
 | 
					 | 
				
			||||||
  Api
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -14,19 +14,3 @@
 | 
				
			|||||||
/* You should have received a copy of the GNU General Public License
 | 
					/* You should have received a copy of the GNU General Public License
 | 
				
			||||||
/* along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					/* along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					 | 
				
			||||||
.spaced {
 | 
					 | 
				
			||||||
  margin: 0.25em 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.typeContainer {
 | 
					 | 
				
			||||||
  display: flex;
 | 
					 | 
				
			||||||
  flex-direction: column;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .desc {
 | 
					 | 
				
			||||||
    font-size: 0.8em;
 | 
					 | 
				
			||||||
    margin-bottom: 0.5em;
 | 
					 | 
				
			||||||
    color: #ccc;
 | 
					 | 
				
			||||||
    z-index: 2;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -20,13 +20,10 @@ import ContentClear from 'material-ui/svg-icons/content/clear';
 | 
				
			|||||||
import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forward';
 | 
					import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forward';
 | 
				
			||||||
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
 | 
					import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { RadioButton, RadioButtonGroup } from 'material-ui/RadioButton';
 | 
					import { Button, Modal, Form, Input, InputAddress, RadioButtons } from '../../ui';
 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Button, Modal, Form, Input, InputAddress } from '../../ui';
 | 
					 | 
				
			||||||
import { ERRORS, validateAbi, validateAddress, validateName } from '../../util/validation';
 | 
					import { ERRORS, validateAbi, validateAddress, validateName } from '../../util/validation';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { eip20, wallet } from '../../contracts/abi';
 | 
					import { eip20, wallet } from '../../contracts/abi';
 | 
				
			||||||
import styles from './addContract.css';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ABI_TYPES = [
 | 
					const ABI_TYPES = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
@ -105,13 +102,12 @@ export default class AddContract extends Component {
 | 
				
			|||||||
    const { abiTypeIndex } = this.state;
 | 
					    const { abiTypeIndex } = this.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <RadioButtonGroup
 | 
					      <RadioButtons
 | 
				
			||||||
        valueSelected={ abiTypeIndex }
 | 
					 | 
				
			||||||
        name='contractType'
 | 
					        name='contractType'
 | 
				
			||||||
 | 
					        value={ abiTypeIndex }
 | 
				
			||||||
 | 
					        values={ this.getAbiTypes() }
 | 
				
			||||||
        onChange={ this.onChangeABIType }
 | 
					        onChange={ this.onChangeABIType }
 | 
				
			||||||
      >
 | 
					      />
 | 
				
			||||||
        { this.renderAbiTypes() }
 | 
					 | 
				
			||||||
      </RadioButtonGroup>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -194,20 +190,13 @@ export default class AddContract extends Component {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  renderAbiTypes () {
 | 
					  getAbiTypes () {
 | 
				
			||||||
    return ABI_TYPES.map((type, index) => (
 | 
					    return ABI_TYPES.map((type, index) => ({
 | 
				
			||||||
      <RadioButton
 | 
					      label: type.label,
 | 
				
			||||||
        className={ styles.spaced }
 | 
					      description: type.description,
 | 
				
			||||||
        value={ index }
 | 
					      key: index,
 | 
				
			||||||
        label={ (
 | 
					      ...type
 | 
				
			||||||
          <div className={ styles.typeContainer }>
 | 
					    }));
 | 
				
			||||||
            <span>{ type.label }</span>
 | 
					 | 
				
			||||||
            <span className={ styles.desc }>{ type.description }</span>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        ) }
 | 
					 | 
				
			||||||
        key={ index }
 | 
					 | 
				
			||||||
      />
 | 
					 | 
				
			||||||
    ));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onNext = () => {
 | 
					  onNext = () => {
 | 
				
			||||||
@ -218,8 +207,8 @@ export default class AddContract extends Component {
 | 
				
			|||||||
    this.setState({ step: this.state.step - 1 });
 | 
					    this.setState({ step: this.state.step - 1 });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onChangeABIType = (event, index) => {
 | 
					  onChangeABIType = (value, index) => {
 | 
				
			||||||
    const abiType = ABI_TYPES[index];
 | 
					    const abiType = value || ABI_TYPES[index];
 | 
				
			||||||
    this.setState({ abiTypeIndex: index, abiType });
 | 
					    this.setState({ abiTypeIndex: index, abiType });
 | 
				
			||||||
    this.onEditAbi(abiType.value);
 | 
					    this.onEditAbi(abiType.value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -15,13 +15,12 @@
 | 
				
			|||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import React, { Component, PropTypes } from 'react';
 | 
					import React, { Component, PropTypes } from 'react';
 | 
				
			||||||
 | 
					import { MenuItem } from 'material-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { AddressSelect, Form, Input, TypedInput } from '../../../ui';
 | 
					import { AddressSelect, Form, Input, Select } from '../../../ui';
 | 
				
			||||||
import { validateAbi } from '../../../util/validation';
 | 
					import { validateAbi } from '../../../util/validation';
 | 
				
			||||||
import { parseAbiType } from '../../../util/abi';
 | 
					import { parseAbiType } from '../../../util/abi';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import styles from '../deployContract.css';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default class DetailsStep extends Component {
 | 
					export default class DetailsStep extends Component {
 | 
				
			||||||
  static contextTypes = {
 | 
					  static contextTypes = {
 | 
				
			||||||
    api: PropTypes.object.isRequired
 | 
					    api: PropTypes.object.isRequired
 | 
				
			||||||
@ -29,24 +28,26 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  static propTypes = {
 | 
					  static propTypes = {
 | 
				
			||||||
    accounts: PropTypes.object.isRequired,
 | 
					    accounts: PropTypes.object.isRequired,
 | 
				
			||||||
    abi: PropTypes.string,
 | 
					
 | 
				
			||||||
    abiError: PropTypes.string,
 | 
					    onFromAddressChange: PropTypes.func.isRequired,
 | 
				
			||||||
    code: PropTypes.string,
 | 
					    onNameChange: PropTypes.func.isRequired,
 | 
				
			||||||
    codeError: PropTypes.string,
 | 
					    onDescriptionChange: PropTypes.func.isRequired,
 | 
				
			||||||
    description: PropTypes.string,
 | 
					    onAbiChange: PropTypes.func.isRequired,
 | 
				
			||||||
    descriptionError: PropTypes.string,
 | 
					    onCodeChange: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					    onParamsChange: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					    onInputsChange: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fromAddress: PropTypes.string,
 | 
					    fromAddress: PropTypes.string,
 | 
				
			||||||
    fromAddressError: PropTypes.string,
 | 
					    fromAddressError: PropTypes.string,
 | 
				
			||||||
    name: PropTypes.string,
 | 
					    name: PropTypes.string,
 | 
				
			||||||
    nameError: PropTypes.string,
 | 
					    nameError: PropTypes.string,
 | 
				
			||||||
    params: PropTypes.array,
 | 
					    description: PropTypes.string,
 | 
				
			||||||
    paramsError: PropTypes.array,
 | 
					    descriptionError: PropTypes.string,
 | 
				
			||||||
    onAbiChange: PropTypes.func.isRequired,
 | 
					    abi: PropTypes.string,
 | 
				
			||||||
    onCodeChange: PropTypes.func.isRequired,
 | 
					    abiError: PropTypes.string,
 | 
				
			||||||
    onFromAddressChange: PropTypes.func.isRequired,
 | 
					    code: PropTypes.string,
 | 
				
			||||||
    onDescriptionChange: PropTypes.func.isRequired,
 | 
					    codeError: PropTypes.string,
 | 
				
			||||||
    onNameChange: PropTypes.func.isRequired,
 | 
					
 | 
				
			||||||
    onParamsChange: PropTypes.func.isRequired,
 | 
					 | 
				
			||||||
    readOnly: PropTypes.bool
 | 
					    readOnly: PropTypes.bool
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -55,7 +56,9 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  state = {
 | 
					  state = {
 | 
				
			||||||
    inputs: []
 | 
					    solcOutput: '',
 | 
				
			||||||
 | 
					    contracts: {},
 | 
				
			||||||
 | 
					    selectedContractIndex: 0
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentDidMount () {
 | 
					  componentDidMount () {
 | 
				
			||||||
@ -63,6 +66,7 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (abi) {
 | 
					    if (abi) {
 | 
				
			||||||
      this.onAbiChange(abi);
 | 
					      this.onAbiChange(abi);
 | 
				
			||||||
 | 
					      this.setState({ solcOutput: abi });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (code) {
 | 
					    if (code) {
 | 
				
			||||||
@ -71,8 +75,19 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    const { accounts } = this.props;
 | 
					    const {
 | 
				
			||||||
    const { abi, abiError, code, codeError, fromAddress, fromAddressError, name, nameError, readOnly } = this.props;
 | 
					      accounts,
 | 
				
			||||||
 | 
					      readOnly,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      fromAddress, fromAddressError,
 | 
				
			||||||
 | 
					      name, nameError,
 | 
				
			||||||
 | 
					      description, descriptionError,
 | 
				
			||||||
 | 
					      abiError,
 | 
				
			||||||
 | 
					      code, codeError
 | 
				
			||||||
 | 
					    } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const { solcOutput, contracts } = this.state;
 | 
				
			||||||
 | 
					    const solc = contracts && Object.keys(contracts).length > 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Form>
 | 
					      <Form>
 | 
				
			||||||
@ -83,18 +98,30 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
          error={ fromAddressError }
 | 
					          error={ fromAddressError }
 | 
				
			||||||
          accounts={ accounts }
 | 
					          accounts={ accounts }
 | 
				
			||||||
          onChange={ this.onFromAddressChange } />
 | 
					          onChange={ this.onFromAddressChange } />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <Input
 | 
					        <Input
 | 
				
			||||||
          label='contract name'
 | 
					          label='contract name'
 | 
				
			||||||
          hint='a name for the deployed contract'
 | 
					          hint='a name for the deployed contract'
 | 
				
			||||||
          error={ nameError }
 | 
					          error={ nameError }
 | 
				
			||||||
          value={ name }
 | 
					          value={ name }
 | 
				
			||||||
          onSubmit={ this.onNameChange } />
 | 
					          onChange={ this.onNameChange } />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <Input
 | 
					        <Input
 | 
				
			||||||
          label='abi'
 | 
					          label='contract description (optional)'
 | 
				
			||||||
          hint='the abi of the contract to deploy'
 | 
					          hint='a description for the contract'
 | 
				
			||||||
 | 
					          error={ descriptionError }
 | 
				
			||||||
 | 
					          value={ description }
 | 
				
			||||||
 | 
					          onChange={ this.onDescriptionChange } />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { this.renderContractSelect() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Input
 | 
				
			||||||
 | 
					          label='abi / solc combined-output'
 | 
				
			||||||
 | 
					          hint='the abi of the contract to deploy or solc combined-output'
 | 
				
			||||||
          error={ abiError }
 | 
					          error={ abiError }
 | 
				
			||||||
          value={ abi }
 | 
					          value={ solcOutput }
 | 
				
			||||||
          onSubmit={ this.onAbiChange }
 | 
					          onChange={ this.onSolcChange }
 | 
				
			||||||
 | 
					          onSubmit={ this.onSolcSubmit }
 | 
				
			||||||
          readOnly={ readOnly } />
 | 
					          readOnly={ readOnly } />
 | 
				
			||||||
        <Input
 | 
					        <Input
 | 
				
			||||||
          label='code'
 | 
					          label='code'
 | 
				
			||||||
@ -102,66 +129,104 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
          error={ codeError }
 | 
					          error={ codeError }
 | 
				
			||||||
          value={ code }
 | 
					          value={ code }
 | 
				
			||||||
          onSubmit={ this.onCodeChange }
 | 
					          onSubmit={ this.onCodeChange }
 | 
				
			||||||
          readOnly={ readOnly } />
 | 
					          readOnly={ readOnly || solc } />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { this.renderConstructorInputs() }
 | 
					 | 
				
			||||||
      </Form>
 | 
					      </Form>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  renderConstructorInputs () {
 | 
					  renderContractSelect () {
 | 
				
			||||||
    const { accounts, params, paramsError } = this.props;
 | 
					    const { contracts } = this.state;
 | 
				
			||||||
    const { inputs } = this.state;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!inputs || !inputs.length) {
 | 
					    if (!contracts || Object.keys(contracts).length === 0) {
 | 
				
			||||||
      return null;
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return inputs.map((input, index) => {
 | 
					    const { selectedContractIndex } = this.state;
 | 
				
			||||||
      const onChange = (value) => this.onParamChange(index, value);
 | 
					    const contractsItems = Object.keys(contracts).map((name, index) => (
 | 
				
			||||||
 | 
					      <MenuItem
 | 
				
			||||||
      const label = `${input.name ? `${input.name}: ` : ''}${input.type}`;
 | 
					        key={ index }
 | 
				
			||||||
      const value = params[index];
 | 
					        label={ name }
 | 
				
			||||||
      const error = paramsError[index];
 | 
					        value={ index }
 | 
				
			||||||
      const param = parseAbiType(input.type);
 | 
					      >
 | 
				
			||||||
 | 
					        { name }
 | 
				
			||||||
 | 
					      </MenuItem>
 | 
				
			||||||
 | 
					    ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <div key={ index } className={ styles.funcparams }>
 | 
					      <Select
 | 
				
			||||||
          <TypedInput
 | 
					        label='select a contract'
 | 
				
			||||||
            label={ label }
 | 
					        onChange={ this.onContractChange }
 | 
				
			||||||
            value={ value }
 | 
					        value={ selectedContractIndex }
 | 
				
			||||||
            error={ error }
 | 
					      >
 | 
				
			||||||
            accounts={ accounts }
 | 
					        { contractsItems }
 | 
				
			||||||
            onChange={ onChange }
 | 
					      </Select>
 | 
				
			||||||
            param={ param }
 | 
					 | 
				
			||||||
          />
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onContractChange = (event, index) => {
 | 
				
			||||||
 | 
					    const { contracts } = this.state;
 | 
				
			||||||
 | 
					    const contractName = Object.keys(contracts)[index];
 | 
				
			||||||
 | 
					    const contract = contracts[contractName];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const { abi, bin } = contract;
 | 
				
			||||||
 | 
					    const code = /^0x/.test(bin) ? bin : `0x${bin}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.setState({ selectedContractIndex: index }, () => {
 | 
				
			||||||
 | 
					      this.onAbiChange(abi);
 | 
				
			||||||
 | 
					      this.onCodeChange(code);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onSolcChange = (event, value) => {
 | 
				
			||||||
 | 
					    // Change triggered only if valid
 | 
				
			||||||
 | 
					    if (this.props.abiError) {
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.onSolcSubmit(value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onSolcSubmit = (value) => {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const solcParsed = JSON.parse(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (!solcParsed || !solcParsed.contracts) {
 | 
				
			||||||
 | 
					        throw new Error('Wrong solc output');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      this.setState({ contracts: solcParsed.contracts }, () => {
 | 
				
			||||||
 | 
					        this.onContractChange(null, 0);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      this.setState({ contracts: null });
 | 
				
			||||||
 | 
					      this.onAbiChange(value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.setState({ solcOutput: value });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onFromAddressChange = (event, fromAddress) => {
 | 
					  onFromAddressChange = (event, fromAddress) => {
 | 
				
			||||||
    const { onFromAddressChange } = this.props;
 | 
					    const { onFromAddressChange } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    onFromAddressChange(fromAddress);
 | 
					    onFromAddressChange(fromAddress);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onNameChange = (name) => {
 | 
					  onNameChange = (event, name) => {
 | 
				
			||||||
    const { onNameChange } = this.props;
 | 
					    const { onNameChange } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    onNameChange(name);
 | 
					    onNameChange(name);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onParamChange = (index, value) => {
 | 
					  onDescriptionChange = (event, description) => {
 | 
				
			||||||
    const { params, onParamsChange } = this.props;
 | 
					    const { onDescriptionChange } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    params[index] = value;
 | 
					    onDescriptionChange(description);
 | 
				
			||||||
    onParamsChange(params);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onAbiChange = (abi) => {
 | 
					  onAbiChange = (abi) => {
 | 
				
			||||||
    const { api } = this.context;
 | 
					    const { api } = this.context;
 | 
				
			||||||
    const { onAbiChange, onParamsChange } = this.props;
 | 
					    const { onAbiChange, onParamsChange, onInputsChange } = this.props;
 | 
				
			||||||
    const { abiError, abiParsed } = validateAbi(abi, api);
 | 
					    const { abiError, abiParsed } = validateAbi(abi, api);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!abiError) {
 | 
					    if (!abiError) {
 | 
				
			||||||
@ -176,10 +241,10 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      onParamsChange(params);
 | 
					      onParamsChange(params);
 | 
				
			||||||
      this.setState({ inputs });
 | 
					      onInputsChange(inputs);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      onParamsChange([]);
 | 
					      onParamsChange([]);
 | 
				
			||||||
      this.setState({ inputs: [] });
 | 
					      onInputsChange([]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    onAbiChange(abi);
 | 
					    onAbiChange(abi);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										17
									
								
								js/src/modals/DeployContract/ParametersStep/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								js/src/modals/DeployContract/ParametersStep/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Ethcore (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 './parametersStep';
 | 
				
			||||||
							
								
								
									
										105
									
								
								js/src/modals/DeployContract/ParametersStep/parametersStep.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								js/src/modals/DeployContract/ParametersStep/parametersStep.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Ethcore (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/>.
 | 
				
			||||||
 | 
					// Copyright 2015, 2016 Ethcore (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 { Form, TypedInput } from '../../../ui';
 | 
				
			||||||
 | 
					import { parseAbiType } from '../../../util/abi';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import styles from '../deployContract.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class ParametersStep extends Component {
 | 
				
			||||||
 | 
					  static contextTypes = {
 | 
				
			||||||
 | 
					    api: PropTypes.object.isRequired
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static propTypes = {
 | 
				
			||||||
 | 
					    accounts: PropTypes.object.isRequired,
 | 
				
			||||||
 | 
					    onParamsChange: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputs: PropTypes.array,
 | 
				
			||||||
 | 
					    params: PropTypes.array,
 | 
				
			||||||
 | 
					    paramsError: PropTypes.array
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  render () {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <Form>
 | 
				
			||||||
 | 
					        { this.renderConstructorInputs() }
 | 
				
			||||||
 | 
					      </Form>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  renderConstructorInputs () {
 | 
				
			||||||
 | 
					    const { accounts, params, paramsError } = this.props;
 | 
				
			||||||
 | 
					    const { inputs } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!inputs || !inputs.length) {
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const inputsComponents = inputs.map((input, index) => {
 | 
				
			||||||
 | 
					      const onChange = (value) => this.onParamChange(index, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const label = `${input.name ? `${input.name}: ` : ''}${input.type}`;
 | 
				
			||||||
 | 
					      const value = params[index];
 | 
				
			||||||
 | 
					      const error = paramsError[index];
 | 
				
			||||||
 | 
					      const param = parseAbiType(input.type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return (
 | 
				
			||||||
 | 
					        <div key={ index } className={ styles.funcparams }>
 | 
				
			||||||
 | 
					          <TypedInput
 | 
				
			||||||
 | 
					            label={ label }
 | 
				
			||||||
 | 
					            value={ value }
 | 
				
			||||||
 | 
					            error={ error }
 | 
				
			||||||
 | 
					            accounts={ accounts }
 | 
				
			||||||
 | 
					            onChange={ onChange }
 | 
				
			||||||
 | 
					            param={ param }
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <div>
 | 
				
			||||||
 | 
					        <p>Choose the contract parameters</p>
 | 
				
			||||||
 | 
					        { inputsComponents }
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onParamChange = (index, value) => {
 | 
				
			||||||
 | 
					    const { params, onParamsChange } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    params[index] = value;
 | 
				
			||||||
 | 
					    onParamsChange(params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -31,3 +31,7 @@
 | 
				
			|||||||
.funcparams {
 | 
					.funcparams {
 | 
				
			||||||
  padding-left: 3em;
 | 
					  padding-left: 3em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					p {
 | 
				
			||||||
 | 
					  color: rgba(255, 255, 255, 0.498039);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,13 +22,19 @@ import { BusyStep, CompletedStep, CopyToClipboard, Button, IdentityIcon, Modal,
 | 
				
			|||||||
import { ERRORS, validateAbi, validateCode, validateName } from '../../util/validation';
 | 
					import { ERRORS, validateAbi, validateCode, validateName } from '../../util/validation';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import DetailsStep from './DetailsStep';
 | 
					import DetailsStep from './DetailsStep';
 | 
				
			||||||
 | 
					import ParametersStep from './ParametersStep';
 | 
				
			||||||
import ErrorStep from './ErrorStep';
 | 
					import ErrorStep from './ErrorStep';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import styles from './deployContract.css';
 | 
					import styles from './deployContract.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ERROR_CODES } from '../../api/transport/error';
 | 
					import { ERROR_CODES } from '../../api/transport/error';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const steps = ['contract details', 'deployment', 'completed'];
 | 
					const STEPS = {
 | 
				
			||||||
 | 
					  CONTRACT_DETAILS: { title: 'contract details' },
 | 
				
			||||||
 | 
					  CONTRACT_PARAMETERS: { title: 'contract parameters' },
 | 
				
			||||||
 | 
					  DEPLOYMENT: { title: 'deployment', waiting: true },
 | 
				
			||||||
 | 
					  COMPLETED: { title: 'completed' }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class DeployContract extends Component {
 | 
					export default class DeployContract extends Component {
 | 
				
			||||||
  static contextTypes = {
 | 
					  static contextTypes = {
 | 
				
			||||||
@ -55,7 +61,6 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
    abiError: ERRORS.invalidAbi,
 | 
					    abiError: ERRORS.invalidAbi,
 | 
				
			||||||
    code: '',
 | 
					    code: '',
 | 
				
			||||||
    codeError: ERRORS.invalidCode,
 | 
					    codeError: ERRORS.invalidCode,
 | 
				
			||||||
    deployState: '',
 | 
					 | 
				
			||||||
    description: '',
 | 
					    description: '',
 | 
				
			||||||
    descriptionError: null,
 | 
					    descriptionError: null,
 | 
				
			||||||
    fromAddress: Object.keys(this.props.accounts)[0],
 | 
					    fromAddress: Object.keys(this.props.accounts)[0],
 | 
				
			||||||
@ -64,9 +69,12 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
    nameError: ERRORS.invalidName,
 | 
					    nameError: ERRORS.invalidName,
 | 
				
			||||||
    params: [],
 | 
					    params: [],
 | 
				
			||||||
    paramsError: [],
 | 
					    paramsError: [],
 | 
				
			||||||
    step: 0,
 | 
					    inputs: [],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    deployState: '',
 | 
				
			||||||
    deployError: null,
 | 
					    deployError: null,
 | 
				
			||||||
    rejected: false
 | 
					    rejected: false,
 | 
				
			||||||
 | 
					    step: 'CONTRACT_DETAILS'
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentWillMount () {
 | 
					  componentWillMount () {
 | 
				
			||||||
@ -95,20 +103,30 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    const { step, deployError, rejected } = this.state;
 | 
					    const { step, deployError, rejected, inputs } = this.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const realStep = Object.keys(STEPS).findIndex((k) => k === step);
 | 
				
			||||||
 | 
					    const realSteps = deployError || rejected
 | 
				
			||||||
 | 
					      ? null
 | 
				
			||||||
 | 
					      : Object.keys(STEPS)
 | 
				
			||||||
 | 
					        .filter((k) => k !== 'CONTRACT_PARAMETERS' || inputs.length > 0)
 | 
				
			||||||
 | 
					        .map((k) => STEPS[k]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const realSteps = deployError || rejected ? null : steps;
 | 
					 | 
				
			||||||
    const title = realSteps
 | 
					    const title = realSteps
 | 
				
			||||||
      ? null
 | 
					      ? null
 | 
				
			||||||
      : (deployError ? 'deployment failed' : 'rejected');
 | 
					      : (deployError ? 'deployment failed' : 'rejected');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const waiting = realSteps
 | 
				
			||||||
 | 
					      ? realSteps.map((s, i) => s.waiting ? i : false).filter((v) => v !== false)
 | 
				
			||||||
 | 
					      : null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Modal
 | 
					      <Modal
 | 
				
			||||||
        actions={ this.renderDialogActions() }
 | 
					        actions={ this.renderDialogActions() }
 | 
				
			||||||
        current={ step }
 | 
					        current={ realStep }
 | 
				
			||||||
        steps={ realSteps }
 | 
					        steps={ realSteps ? realSteps.map((s) => s.title) : null }
 | 
				
			||||||
        title={ title }
 | 
					        title={ title }
 | 
				
			||||||
        waiting={ realSteps ? [1] : null }
 | 
					        waiting={ waiting }
 | 
				
			||||||
        visible
 | 
					        visible
 | 
				
			||||||
        scroll>
 | 
					        scroll>
 | 
				
			||||||
        { this.renderStep() }
 | 
					        { this.renderStep() }
 | 
				
			||||||
@ -146,20 +164,29 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (step) {
 | 
					    switch (step) {
 | 
				
			||||||
      case 0:
 | 
					      case 'CONTRACT_DETAILS':
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
          cancelBtn,
 | 
					          cancelBtn,
 | 
				
			||||||
          <Button
 | 
					          <Button
 | 
				
			||||||
            disabled={ !isValid }
 | 
					            disabled={ !isValid }
 | 
				
			||||||
 | 
					            icon={ <IdentityIcon button address={ fromAddress } /> }
 | 
				
			||||||
 | 
					            label='Next'
 | 
				
			||||||
 | 
					            onClick={ this.onParametersStep } />
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case 'CONTRACT_PARAMETERS':
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					          cancelBtn,
 | 
				
			||||||
 | 
					          <Button
 | 
				
			||||||
            icon={ <IdentityIcon button address={ fromAddress } /> }
 | 
					            icon={ <IdentityIcon button address={ fromAddress } /> }
 | 
				
			||||||
            label='Create'
 | 
					            label='Create'
 | 
				
			||||||
            onClick={ this.onDeployStart } />
 | 
					            onClick={ this.onDeployStart } />
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      case 1:
 | 
					      case 'DEPLOYMENT':
 | 
				
			||||||
        return [ closeBtn ];
 | 
					        return [ closeBtn ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      case 2:
 | 
					      case 'COMPLETED':
 | 
				
			||||||
        return [ closeBtnOk ];
 | 
					        return [ closeBtnOk ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -184,21 +211,33 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (step) {
 | 
					    switch (step) {
 | 
				
			||||||
      case 0:
 | 
					      case 'CONTRACT_DETAILS':
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
          <DetailsStep
 | 
					          <DetailsStep
 | 
				
			||||||
            { ...this.state }
 | 
					            { ...this.state }
 | 
				
			||||||
            readOnly={ readOnly }
 | 
					 | 
				
			||||||
            accounts={ accounts }
 | 
					            accounts={ accounts }
 | 
				
			||||||
            onAbiChange={ this.onAbiChange }
 | 
					            readOnly={ readOnly }
 | 
				
			||||||
            onCodeChange={ this.onCodeChange }
 | 
					 | 
				
			||||||
            onFromAddressChange={ this.onFromAddressChange }
 | 
					            onFromAddressChange={ this.onFromAddressChange }
 | 
				
			||||||
            onDescriptionChange={ this.onDescriptionChange }
 | 
					            onDescriptionChange={ this.onDescriptionChange }
 | 
				
			||||||
            onNameChange={ this.onNameChange }
 | 
					            onNameChange={ this.onNameChange }
 | 
				
			||||||
            onParamsChange={ this.onParamsChange } />
 | 
					            onAbiChange={ this.onAbiChange }
 | 
				
			||||||
 | 
					            onCodeChange={ this.onCodeChange }
 | 
				
			||||||
 | 
					            onParamsChange={ this.onParamsChange }
 | 
				
			||||||
 | 
					            onInputsChange={ this.onInputsChange }
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      case 1:
 | 
					      case 'CONTRACT_PARAMETERS':
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					          <ParametersStep
 | 
				
			||||||
 | 
					            { ...this.state }
 | 
				
			||||||
 | 
					            readOnly={ readOnly }
 | 
				
			||||||
 | 
					            accounts={ accounts }
 | 
				
			||||||
 | 
					            onParamsChange={ this.onParamsChange }
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case 'DEPLOYMENT':
 | 
				
			||||||
        const body = txhash
 | 
					        const body = txhash
 | 
				
			||||||
          ? <TxHash hash={ txhash } />
 | 
					          ? <TxHash hash={ txhash } />
 | 
				
			||||||
          : null;
 | 
					          : null;
 | 
				
			||||||
@ -210,7 +249,7 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
          </BusyStep>
 | 
					          </BusyStep>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      case 2:
 | 
					      case 'COMPLETED':
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
          <CompletedStep>
 | 
					          <CompletedStep>
 | 
				
			||||||
            <div>Your contract has been deployed at</div>
 | 
					            <div>Your contract has been deployed at</div>
 | 
				
			||||||
@ -225,12 +264,23 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onParametersStep = () => {
 | 
				
			||||||
 | 
					    const { inputs } = this.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (inputs.length) {
 | 
				
			||||||
 | 
					      return this.setState({ step: 'CONTRACT_PARAMETERS' });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.onDeployStart();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onDescriptionChange = (description) => {
 | 
					  onDescriptionChange = (description) => {
 | 
				
			||||||
    this.setState({ description, descriptionError: null });
 | 
					    this.setState({ description, descriptionError: null });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onFromAddressChange = (fromAddress) => {
 | 
					  onFromAddressChange = (fromAddress) => {
 | 
				
			||||||
    const { api } = this.context;
 | 
					    const { api } = this.context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const fromAddressError = api.util.isAddressValid(fromAddress)
 | 
					    const fromAddressError = api.util.isAddressValid(fromAddress)
 | 
				
			||||||
      ? null
 | 
					      ? null
 | 
				
			||||||
      : 'a valid account as the contract owner needs to be selected';
 | 
					      : 'a valid account as the contract owner needs to be selected';
 | 
				
			||||||
@ -246,6 +296,10 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
    this.setState({ params });
 | 
					    this.setState({ params });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onInputsChange = (inputs) => {
 | 
				
			||||||
 | 
					    this.setState({ inputs });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onAbiChange = (abi) => {
 | 
					  onAbiChange = (abi) => {
 | 
				
			||||||
    const { api } = this.context;
 | 
					    const { api } = this.context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -267,7 +321,7 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
      from: fromAddress
 | 
					      from: fromAddress
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.setState({ step: 1 });
 | 
					    this.setState({ step: 'DEPLOYMENT' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    api
 | 
					    api
 | 
				
			||||||
      .newContract(abiParsed)
 | 
					      .newContract(abiParsed)
 | 
				
			||||||
@ -286,7 +340,7 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
        ])
 | 
					        ])
 | 
				
			||||||
        .then(() => {
 | 
					        .then(() => {
 | 
				
			||||||
          console.log(`contract deployed at ${address}`);
 | 
					          console.log(`contract deployed at ${address}`);
 | 
				
			||||||
          this.setState({ step: 2, address });
 | 
					          this.setState({ step: 'DEPLOYMENT', address });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .catch((error) => {
 | 
					      .catch((error) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { newError } from '../ui/Errors/actions';
 | 
					import { newError } from '../ui/Errors/actions';
 | 
				
			||||||
import { setAddressImage } from './providers/imagesActions';
 | 
					import { setAddressImage } from './providers/imagesActions';
 | 
				
			||||||
import { clearStatusLogs, toggleStatusLogs } from './providers/statusActions';
 | 
					import { clearStatusLogs, toggleStatusLogs, toggleStatusRefresh } from './providers/statusActions';
 | 
				
			||||||
import { toggleView } from '../views/Settings';
 | 
					import { toggleView } from '../views/Settings';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export {
 | 
					export {
 | 
				
			||||||
@ -24,5 +24,6 @@ export {
 | 
				
			|||||||
  clearStatusLogs,
 | 
					  clearStatusLogs,
 | 
				
			||||||
  setAddressImage,
 | 
					  setAddressImage,
 | 
				
			||||||
  toggleStatusLogs,
 | 
					  toggleStatusLogs,
 | 
				
			||||||
 | 
					  toggleStatusRefresh,
 | 
				
			||||||
  toggleView
 | 
					  toggleView
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -15,32 +15,29 @@
 | 
				
			|||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { statusBlockNumber, statusCollection, statusLogs } from './statusActions';
 | 
					import { statusBlockNumber, statusCollection, statusLogs } from './statusActions';
 | 
				
			||||||
 | 
					import { isEqual } from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Status {
 | 
					export default class Status {
 | 
				
			||||||
  constructor (store, api) {
 | 
					  constructor (store, api) {
 | 
				
			||||||
    this._api = api;
 | 
					    this._api = api;
 | 
				
			||||||
    this._store = store;
 | 
					    this._store = store;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this._pingable = false;
 | 
				
			||||||
 | 
					    this._apiStatus = {};
 | 
				
			||||||
 | 
					    this._status = {};
 | 
				
			||||||
 | 
					    this._longStatus = {};
 | 
				
			||||||
 | 
					    this._minerSettings = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this._pollPingTimeoutId = null;
 | 
				
			||||||
 | 
					    this._longStatusTimeoutId = null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  start () {
 | 
					  start () {
 | 
				
			||||||
    this._subscribeBlockNumber();
 | 
					    this._subscribeBlockNumber();
 | 
				
			||||||
    this._pollPing();
 | 
					    this._pollPing();
 | 
				
			||||||
    this._pollStatus();
 | 
					    this._pollStatus();
 | 
				
			||||||
 | 
					    this._pollLongStatus();
 | 
				
			||||||
    this._pollLogs();
 | 
					    this._pollLogs();
 | 
				
			||||||
    this._fetchEnode();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  _fetchEnode () {
 | 
					 | 
				
			||||||
    this._api.parity
 | 
					 | 
				
			||||||
      .enode()
 | 
					 | 
				
			||||||
      .then((enode) => {
 | 
					 | 
				
			||||||
        this._store.dispatch(statusCollection({ enode }));
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
      .catch(() => {
 | 
					 | 
				
			||||||
        window.setTimeout(() => {
 | 
					 | 
				
			||||||
          this._fetchEnode();
 | 
					 | 
				
			||||||
        }, 1000);
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _subscribeBlockNumber () {
 | 
					  _subscribeBlockNumber () {
 | 
				
			||||||
@ -66,10 +63,43 @@ export default class Status {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Pinging should be smart. It should only
 | 
				
			||||||
 | 
					   * be used when the UI is connecting or the
 | 
				
			||||||
 | 
					   * Node is deconnected.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @see src/views/Connection/connection.js
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  _shouldPing = () => {
 | 
				
			||||||
 | 
					    const { isConnected, isConnecting } = this._apiStatus;
 | 
				
			||||||
 | 
					    return isConnecting || !isConnected;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _stopPollPing = () => {
 | 
				
			||||||
 | 
					    if (!this._pollPingTimeoutId) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    clearTimeout(this._pollPingTimeoutId);
 | 
				
			||||||
 | 
					    this._pollPingTimeoutId = null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _pollPing = () => {
 | 
					  _pollPing = () => {
 | 
				
			||||||
    const dispatch = (status, timeout = 500) => {
 | 
					    // Already pinging, don't try again
 | 
				
			||||||
      this._store.dispatch(statusCollection({ isPingable: status }));
 | 
					    if (this._pollPingTimeoutId) {
 | 
				
			||||||
      setTimeout(this._pollPing, timeout);
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const dispatch = (pingable, timeout = 1000) => {
 | 
				
			||||||
 | 
					      if (pingable !== this._pingable) {
 | 
				
			||||||
 | 
					        this._pingable = pingable;
 | 
				
			||||||
 | 
					        this._store.dispatch(statusCollection({ isPingable: pingable }));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      this._pollPingTimeoutId = setTimeout(() => {
 | 
				
			||||||
 | 
					        this._stopPollPing();
 | 
				
			||||||
 | 
					        this._pollPing();
 | 
				
			||||||
 | 
					      }, timeout);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fetch('/', { method: 'HEAD' })
 | 
					    fetch('/', { method: 'HEAD' })
 | 
				
			||||||
@ -88,61 +118,162 @@ export default class Status {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _pollStatus = () => {
 | 
					  _pollStatus = () => {
 | 
				
			||||||
    const { secureToken, isConnected, isConnecting, needsToken } = this._api;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const nextTimeout = (timeout = 1000) => {
 | 
					    const nextTimeout = (timeout = 1000) => {
 | 
				
			||||||
      setTimeout(this._pollStatus, timeout);
 | 
					      setTimeout(this._pollStatus, timeout);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this._store.dispatch(statusCollection({ isConnected, isConnecting, needsToken, secureToken }));
 | 
					    const { isConnected, isConnecting, needsToken, secureToken } = this._api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const apiStatus = {
 | 
				
			||||||
 | 
					      isConnected,
 | 
				
			||||||
 | 
					      isConnecting,
 | 
				
			||||||
 | 
					      needsToken,
 | 
				
			||||||
 | 
					      secureToken
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const gotReconnected = !this._apiStatus.isConnected && apiStatus.isConnected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (gotReconnected) {
 | 
				
			||||||
 | 
					      this._pollLongStatus();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!isEqual(apiStatus, this._apiStatus)) {
 | 
				
			||||||
 | 
					      this._store.dispatch(statusCollection(apiStatus));
 | 
				
			||||||
 | 
					      this._apiStatus = apiStatus;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Ping if necessary, otherwise stop pinging
 | 
				
			||||||
 | 
					    if (this._shouldPing()) {
 | 
				
			||||||
 | 
					      this._pollPing();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this._stopPollPing();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!isConnected) {
 | 
					    if (!isConnected) {
 | 
				
			||||||
      nextTimeout(250);
 | 
					      return nextTimeout(250);
 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const { refreshStatus } = this._store.getState().nodeStatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const statusPromises = [ this._api.eth.syncing() ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (refreshStatus) {
 | 
				
			||||||
 | 
					      statusPromises.push(this._api.eth.hashrate());
 | 
				
			||||||
 | 
					      statusPromises.push(this._api.parity.netPeers());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Promise
 | 
				
			||||||
 | 
					      .all(statusPromises)
 | 
				
			||||||
 | 
					      .then((statusResults) => {
 | 
				
			||||||
 | 
					        const status = statusResults.length === 1
 | 
				
			||||||
 | 
					          ? {
 | 
				
			||||||
 | 
					            syncing: statusResults[0]
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          : {
 | 
				
			||||||
 | 
					            syncing: statusResults[0],
 | 
				
			||||||
 | 
					            hashrate: statusResults[1],
 | 
				
			||||||
 | 
					            netPeers: statusResults[2]
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!isEqual(status, this._status)) {
 | 
				
			||||||
 | 
					          this._store.dispatch(statusCollection(status));
 | 
				
			||||||
 | 
					          this._status = status;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nextTimeout();
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch((error) => {
 | 
				
			||||||
 | 
					        console.error('_pollStatus', error);
 | 
				
			||||||
 | 
					        nextTimeout(250);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Miner settings should never changes unless
 | 
				
			||||||
 | 
					   * Parity is restarted, or if the values are changed
 | 
				
			||||||
 | 
					   * from the UI
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  _pollMinerSettings = () => {
 | 
				
			||||||
 | 
					    Promise
 | 
				
			||||||
 | 
					      .all([
 | 
				
			||||||
 | 
					        this._api.eth.coinbase(),
 | 
				
			||||||
 | 
					        this._api.parity.extraData(),
 | 
				
			||||||
 | 
					        this._api.parity.minGasPrice(),
 | 
				
			||||||
 | 
					        this._api.parity.gasFloorTarget()
 | 
				
			||||||
 | 
					      ])
 | 
				
			||||||
 | 
					      .then(([
 | 
				
			||||||
 | 
					        coinbase, extraData, minGasPrice, gasFloorTarget
 | 
				
			||||||
 | 
					      ]) => {
 | 
				
			||||||
 | 
					        const minerSettings = {
 | 
				
			||||||
 | 
					          coinbase,
 | 
				
			||||||
 | 
					          extraData,
 | 
				
			||||||
 | 
					          minGasPrice,
 | 
				
			||||||
 | 
					          gasFloorTarget
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!isEqual(minerSettings, this._minerSettings)) {
 | 
				
			||||||
 | 
					          this._store.dispatch(statusCollection(minerSettings));
 | 
				
			||||||
 | 
					          this._minerSettings = minerSettings;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch((error) => {
 | 
				
			||||||
 | 
					        console.error('_pollMinerSettings', error);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * The data fetched here should not change
 | 
				
			||||||
 | 
					   * unless Parity is restarted. They are thus
 | 
				
			||||||
 | 
					   * fetched every 30s just in case, and whenever
 | 
				
			||||||
 | 
					   * the client got reconnected.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  _pollLongStatus = () => {
 | 
				
			||||||
 | 
					    const nextTimeout = (timeout = 30000) => {
 | 
				
			||||||
 | 
					      if (this._longStatusTimeoutId) {
 | 
				
			||||||
 | 
					        clearTimeout(this._longStatusTimeoutId);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      this._longStatusTimeoutId = setTimeout(this._pollLongStatus, timeout);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Poll Miner settings just in case
 | 
				
			||||||
 | 
					    this._pollMinerSettings();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Promise
 | 
					    Promise
 | 
				
			||||||
      .all([
 | 
					      .all([
 | 
				
			||||||
        this._api.web3.clientVersion(),
 | 
					        this._api.web3.clientVersion(),
 | 
				
			||||||
        this._api.eth.coinbase(),
 | 
					 | 
				
			||||||
        this._api.parity.defaultExtraData(),
 | 
					        this._api.parity.defaultExtraData(),
 | 
				
			||||||
        this._api.parity.extraData(),
 | 
					 | 
				
			||||||
        this._api.parity.gasFloorTarget(),
 | 
					 | 
				
			||||||
        this._api.eth.hashrate(),
 | 
					 | 
				
			||||||
        this._api.parity.minGasPrice(),
 | 
					 | 
				
			||||||
        this._api.parity.netChain(),
 | 
					        this._api.parity.netChain(),
 | 
				
			||||||
        this._api.parity.netPeers(),
 | 
					 | 
				
			||||||
        this._api.parity.netPort(),
 | 
					        this._api.parity.netPort(),
 | 
				
			||||||
        this._api.parity.nodeName(),
 | 
					 | 
				
			||||||
        this._api.parity.rpcSettings(),
 | 
					        this._api.parity.rpcSettings(),
 | 
				
			||||||
        this._api.eth.syncing()
 | 
					        this._api.parity.enode()
 | 
				
			||||||
      ])
 | 
					      ])
 | 
				
			||||||
      .then(([clientVersion, coinbase, defaultExtraData, extraData, gasFloorTarget, hashrate, minGasPrice, netChain, netPeers, netPort, nodeName, rpcSettings, syncing, traceMode]) => {
 | 
					      .then(([
 | 
				
			||||||
 | 
					        clientVersion, defaultExtraData, netChain, netPort, rpcSettings, enode
 | 
				
			||||||
 | 
					      ]) => {
 | 
				
			||||||
        const isTest = netChain === 'morden' || netChain === 'testnet';
 | 
					        const isTest = netChain === 'morden' || netChain === 'testnet';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this._store.dispatch(statusCollection({
 | 
					        const longStatus = {
 | 
				
			||||||
          clientVersion,
 | 
					          clientVersion,
 | 
				
			||||||
          coinbase,
 | 
					 | 
				
			||||||
          defaultExtraData,
 | 
					          defaultExtraData,
 | 
				
			||||||
          extraData,
 | 
					 | 
				
			||||||
          gasFloorTarget,
 | 
					 | 
				
			||||||
          hashrate,
 | 
					 | 
				
			||||||
          minGasPrice,
 | 
					 | 
				
			||||||
          netChain,
 | 
					          netChain,
 | 
				
			||||||
          netPeers,
 | 
					 | 
				
			||||||
          netPort,
 | 
					          netPort,
 | 
				
			||||||
          nodeName,
 | 
					 | 
				
			||||||
          rpcSettings,
 | 
					          rpcSettings,
 | 
				
			||||||
          syncing,
 | 
					          enode,
 | 
				
			||||||
          isTest,
 | 
					          isTest
 | 
				
			||||||
          traceMode
 | 
					        };
 | 
				
			||||||
        }));
 | 
					
 | 
				
			||||||
      })
 | 
					        if (!isEqual(longStatus, this._longStatus)) {
 | 
				
			||||||
      .catch((error) => {
 | 
					          this._store.dispatch(statusCollection(longStatus));
 | 
				
			||||||
        console.error('_pollStatus', error);
 | 
					          this._longStatus = longStatus;
 | 
				
			||||||
      });
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        nextTimeout();
 | 
					        nextTimeout();
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch((error) => {
 | 
				
			||||||
 | 
					        console.error('_pollLongStatus', error);
 | 
				
			||||||
 | 
					        nextTimeout(250);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _pollLogs = () => {
 | 
					  _pollLogs = () => {
 | 
				
			||||||
 | 
				
			|||||||
@ -47,3 +47,10 @@ export function clearStatusLogs () {
 | 
				
			|||||||
    type: 'clearStatusLogs'
 | 
					    type: 'clearStatusLogs'
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function toggleStatusRefresh (refreshStatus) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: 'toggleStatusRefresh',
 | 
				
			||||||
 | 
					    refreshStatus
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -38,12 +38,13 @@ const initialState = {
 | 
				
			|||||||
    max: new BigNumber(0)
 | 
					    max: new BigNumber(0)
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  netPort: new BigNumber(0),
 | 
					  netPort: new BigNumber(0),
 | 
				
			||||||
  nodeName: '',
 | 
					 | 
				
			||||||
  rpcSettings: {},
 | 
					  rpcSettings: {},
 | 
				
			||||||
  syncing: false,
 | 
					  syncing: false,
 | 
				
			||||||
  isApiConnected: true,
 | 
					  isConnected: false,
 | 
				
			||||||
  isPingConnected: true,
 | 
					  isConnecting: false,
 | 
				
			||||||
 | 
					  isPingable: false,
 | 
				
			||||||
  isTest: false,
 | 
					  isTest: false,
 | 
				
			||||||
 | 
					  refreshStatus: false,
 | 
				
			||||||
  traceMode: undefined
 | 
					  traceMode: undefined
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -74,5 +75,10 @@ export default handleActions({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  clearStatusLogs (state, action) {
 | 
					  clearStatusLogs (state, action) {
 | 
				
			||||||
    return Object.assign({}, state, { devLogs: [] });
 | 
					    return Object.assign({}, state, { devLogs: [] });
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  toggleStatusRefresh (state, action) {
 | 
				
			||||||
 | 
					    const { refreshStatus } = action;
 | 
				
			||||||
 | 
					    return Object.assign({}, state, { refreshStatus });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}, initialState);
 | 
					}, initialState);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										17
									
								
								js/src/ui/Form/RadioButtons/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								js/src/ui/Form/RadioButtons/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Ethcore (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 './radioButtons';
 | 
				
			||||||
							
								
								
									
										32
									
								
								js/src/ui/Form/RadioButtons/radioButtons.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								js/src/ui/Form/RadioButtons/radioButtons.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					/* Copyright 2015, 2016 Ethcore (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/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.spaced {
 | 
				
			||||||
 | 
					  margin: 0.25em 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.typeContainer {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .desc {
 | 
				
			||||||
 | 
					    font-size: 0.8em;
 | 
				
			||||||
 | 
					    margin-bottom: 0.5em;
 | 
				
			||||||
 | 
					    color: #ccc;
 | 
				
			||||||
 | 
					    z-index: 2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										100
									
								
								js/src/ui/Form/RadioButtons/radioButtons.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								js/src/ui/Form/RadioButtons/radioButtons.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Ethcore (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 { RadioButton, RadioButtonGroup } from 'material-ui/RadioButton';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import styles from './radioButtons.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class RadioButtons extends Component {
 | 
				
			||||||
 | 
					  static propTypes = {
 | 
				
			||||||
 | 
					    onChange: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					    values: PropTypes.array.isRequired,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    value: PropTypes.any,
 | 
				
			||||||
 | 
					    name: PropTypes.string
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static defaultProps = {
 | 
				
			||||||
 | 
					    value: 0,
 | 
				
			||||||
 | 
					    name: ''
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  render () {
 | 
				
			||||||
 | 
					    const { value, values } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const index = parseInt(value);
 | 
				
			||||||
 | 
					    const selectedValue = typeof value !== 'object' ? values[index] : value;
 | 
				
			||||||
 | 
					    const key = this.getKey(selectedValue, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <RadioButtonGroup
 | 
				
			||||||
 | 
					        valueSelected={ key }
 | 
				
			||||||
 | 
					        name={ name }
 | 
				
			||||||
 | 
					        onChange={ this.onChange }
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        { this.renderContent() }
 | 
				
			||||||
 | 
					      </RadioButtonGroup>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  renderContent () {
 | 
				
			||||||
 | 
					    const { values } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return values.map((value, index) => {
 | 
				
			||||||
 | 
					      const label = typeof value === 'string' ? value : value.label || '';
 | 
				
			||||||
 | 
					      const description = (typeof value !== 'string' && value.description) || null;
 | 
				
			||||||
 | 
					      const key = this.getKey(value, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return (
 | 
				
			||||||
 | 
					        <RadioButton
 | 
				
			||||||
 | 
					          className={ styles.spaced }
 | 
				
			||||||
 | 
					          key={ index }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          value={ key }
 | 
				
			||||||
 | 
					          label={ (
 | 
				
			||||||
 | 
					            <div className={ styles.typeContainer }>
 | 
				
			||||||
 | 
					              <span>{ label }</span>
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                description
 | 
				
			||||||
 | 
					                ? (
 | 
				
			||||||
 | 
					                  <span className={ styles.desc }>{ description }</span>
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                : null
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          ) }
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getKey (value, index) {
 | 
				
			||||||
 | 
					    if (typeof value !== 'string') {
 | 
				
			||||||
 | 
					      return typeof value.key === 'undefined' ? index : value.key;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return index;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onChange = (event, index) => {
 | 
				
			||||||
 | 
					    const { onChange, values } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const value = values[index] || values.find((v) => v.key === index);
 | 
				
			||||||
 | 
					    onChange(value, index);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -23,6 +23,7 @@ import InputAddressSelect from './InputAddressSelect';
 | 
				
			|||||||
import InputChip from './InputChip';
 | 
					import InputChip from './InputChip';
 | 
				
			||||||
import InputInline from './InputInline';
 | 
					import InputInline from './InputInline';
 | 
				
			||||||
import Select from './Select';
 | 
					import Select from './Select';
 | 
				
			||||||
 | 
					import RadioButtons from './RadioButtons';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default from './form';
 | 
					export default from './form';
 | 
				
			||||||
export {
 | 
					export {
 | 
				
			||||||
@ -34,5 +35,6 @@ export {
 | 
				
			|||||||
  InputAddressSelect,
 | 
					  InputAddressSelect,
 | 
				
			||||||
  InputChip,
 | 
					  InputChip,
 | 
				
			||||||
  InputInline,
 | 
					  InputInline,
 | 
				
			||||||
  Select
 | 
					  Select,
 | 
				
			||||||
 | 
					  RadioButtons
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -43,7 +43,7 @@ class Modal extends Component {
 | 
				
			|||||||
    waiting: PropTypes.array,
 | 
					    waiting: PropTypes.array,
 | 
				
			||||||
    scroll: PropTypes.bool,
 | 
					    scroll: PropTypes.bool,
 | 
				
			||||||
    steps: PropTypes.array,
 | 
					    steps: PropTypes.array,
 | 
				
			||||||
    title: React.PropTypes.oneOfType([
 | 
					    title: PropTypes.oneOfType([
 | 
				
			||||||
      PropTypes.node, PropTypes.string
 | 
					      PropTypes.node, PropTypes.string
 | 
				
			||||||
    ]),
 | 
					    ]),
 | 
				
			||||||
    visible: PropTypes.bool.isRequired,
 | 
					    visible: PropTypes.bool.isRequired,
 | 
				
			||||||
 | 
				
			|||||||
@ -29,7 +29,7 @@ import ContextProvider from './ContextProvider';
 | 
				
			|||||||
import CopyToClipboard from './CopyToClipboard';
 | 
					import CopyToClipboard from './CopyToClipboard';
 | 
				
			||||||
import Editor from './Editor';
 | 
					import Editor from './Editor';
 | 
				
			||||||
import Errors from './Errors';
 | 
					import Errors from './Errors';
 | 
				
			||||||
import Form, { AddressSelect, FormWrap, TypedInput, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select } from './Form';
 | 
					import Form, { AddressSelect, FormWrap, TypedInput, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select, RadioButtons } from './Form';
 | 
				
			||||||
import IdentityIcon from './IdentityIcon';
 | 
					import IdentityIcon from './IdentityIcon';
 | 
				
			||||||
import IdentityName from './IdentityName';
 | 
					import IdentityName from './IdentityName';
 | 
				
			||||||
import MethodDecoding from './MethodDecoding';
 | 
					import MethodDecoding from './MethodDecoding';
 | 
				
			||||||
@ -78,6 +78,7 @@ export {
 | 
				
			|||||||
  muiTheme,
 | 
					  muiTheme,
 | 
				
			||||||
  Page,
 | 
					  Page,
 | 
				
			||||||
  ParityBackground,
 | 
					  ParityBackground,
 | 
				
			||||||
 | 
					  RadioButtons,
 | 
				
			||||||
  SignerIcon,
 | 
					  SignerIcon,
 | 
				
			||||||
  Tags,
 | 
					  Tags,
 | 
				
			||||||
  Tooltip,
 | 
					  Tooltip,
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ import React, { Component, PropTypes } from 'react';
 | 
				
			|||||||
import { bindActionCreators } from 'redux';
 | 
					import { bindActionCreators } from 'redux';
 | 
				
			||||||
import { connect } from 'react-redux';
 | 
					import { connect } from 'react-redux';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { clearStatusLogs, toggleStatusLogs } from '../../../../redux/actions';
 | 
					import { clearStatusLogs, toggleStatusLogs, toggleStatusRefresh } from '../../../../redux/actions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Debug from '../../components/Debug';
 | 
					import Debug from '../../components/Debug';
 | 
				
			||||||
import Status from '../../components/Status';
 | 
					import Status from '../../components/Status';
 | 
				
			||||||
@ -31,6 +31,14 @@ class StatusPage extends Component {
 | 
				
			|||||||
    actions: PropTypes.object.isRequired
 | 
					    actions: PropTypes.object.isRequired
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  componentWillMount () {
 | 
				
			||||||
 | 
					    this.props.actions.toggleStatusRefresh(true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  componentWillUnmount () {
 | 
				
			||||||
 | 
					    this.props.actions.toggleStatusRefresh(false);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <div className={ styles.body }>
 | 
					      <div className={ styles.body }>
 | 
				
			||||||
@ -49,7 +57,8 @@ function mapDispatchToProps (dispatch) {
 | 
				
			|||||||
  return {
 | 
					  return {
 | 
				
			||||||
    actions: bindActionCreators({
 | 
					    actions: bindActionCreators({
 | 
				
			||||||
      clearStatusLogs,
 | 
					      clearStatusLogs,
 | 
				
			||||||
      toggleStatusLogs
 | 
					      toggleStatusLogs,
 | 
				
			||||||
 | 
					      toggleStatusRefresh
 | 
				
			||||||
    }, dispatch)
 | 
					    }, dispatch)
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										45
									
								
								js/test/npmLibrary.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								js/test/npmLibrary.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Ethcore (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/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try {
 | 
				
			||||||
 | 
					  var Api = require('../.npmjs/library.js').Api;
 | 
				
			||||||
 | 
					  var Abi = require('../.npmjs/library.js').Abi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (typeof Api !== 'function') {
 | 
				
			||||||
 | 
					    throw new Error('No Api');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (typeof Abi !== 'function') {
 | 
				
			||||||
 | 
					    throw new Error('No Abi');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var transport = new Api.Transport.Http('http://localhost:8545');
 | 
				
			||||||
 | 
					  var api = new Api(transport);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  api.eth
 | 
				
			||||||
 | 
					    .blockNumber()
 | 
				
			||||||
 | 
					    .then((block) => {
 | 
				
			||||||
 | 
					      console.log('library working fine', '(block #' + block.toFormat() + ')');
 | 
				
			||||||
 | 
					      process.exit(0);
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .catch(() => {
 | 
				
			||||||
 | 
					      console.log('library working fine (disconnected)');
 | 
				
			||||||
 | 
					      process.exit(0);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					} catch (e) {
 | 
				
			||||||
 | 
					  console.error('An error occured:', e.toString().split('\n')[0]);
 | 
				
			||||||
 | 
					  process.exit(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -26,6 +26,7 @@ const DEST = process.env.BUILD_DEST || '.build';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
  context: path.join(__dirname, './src'),
 | 
					  context: path.join(__dirname, './src'),
 | 
				
			||||||
 | 
					  target: 'node',
 | 
				
			||||||
  entry: {
 | 
					  entry: {
 | 
				
			||||||
    // library
 | 
					    // library
 | 
				
			||||||
    'inject': ['./web3.js'],
 | 
					    'inject': ['./web3.js'],
 | 
				
			||||||
@ -34,9 +35,18 @@ module.exports = {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  output: {
 | 
					  output: {
 | 
				
			||||||
    path: path.join(__dirname, DEST),
 | 
					    path: path.join(__dirname, DEST),
 | 
				
			||||||
    filename: '[name].js'
 | 
					    filename: '[name].js',
 | 
				
			||||||
 | 
					    library: '[name].js',
 | 
				
			||||||
 | 
					    libraryTarget: 'umd'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  externals: {
 | 
				
			||||||
 | 
					    'node-fetch': 'node-fetch',
 | 
				
			||||||
 | 
					    'vertx': 'vertx'
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  module: {
 | 
					  module: {
 | 
				
			||||||
 | 
					    noParse: [
 | 
				
			||||||
 | 
					      /babel-polyfill/
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    loaders: [
 | 
					    loaders: [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        test: /\.js$/,
 | 
					        test: /\.js$/,
 | 
				
			||||||
 | 
				
			|||||||
@ -24,13 +24,23 @@ const isProd = ENV === 'production';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
  context: path.join(__dirname, './src'),
 | 
					  context: path.join(__dirname, './src'),
 | 
				
			||||||
 | 
					  target: 'node',
 | 
				
			||||||
  entry: 'library.js',
 | 
					  entry: 'library.js',
 | 
				
			||||||
  output: {
 | 
					  output: {
 | 
				
			||||||
    path: path.join(__dirname, '.npmjs'),
 | 
					    path: path.join(__dirname, '.npmjs'),
 | 
				
			||||||
    filename: 'library.js',
 | 
					    filename: 'library.js',
 | 
				
			||||||
    libraryTarget: 'commonjs'
 | 
					    library: 'Parity',
 | 
				
			||||||
 | 
					    libraryTarget: 'umd',
 | 
				
			||||||
 | 
					    umdNamedDefine: true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  externals: {
 | 
				
			||||||
 | 
					    'node-fetch': 'node-fetch',
 | 
				
			||||||
 | 
					    'vertx': 'vertx'
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  module: {
 | 
					  module: {
 | 
				
			||||||
 | 
					    noParse: [
 | 
				
			||||||
 | 
					      /babel-polyfill/
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    loaders: [
 | 
					    loaders: [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        test: /(\.jsx|\.js)$/,
 | 
					        test: /(\.jsx|\.js)$/,
 | 
				
			||||||
 | 
				
			|||||||
@ -112,7 +112,7 @@ fn should_be_able_to_set_meta() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
 | 
						let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
 | 
				
			||||||
	let res = tester.io.handle_request_sync(request);
 | 
						let res = tester.io.handle_request_sync(request);
 | 
				
			||||||
	let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"{}\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid, uuid);
 | 
						let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid);
 | 
				
			||||||
	assert_eq!(res, Some(response));
 | 
						assert_eq!(res, Some(response));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user