TxForm.js 4.57 KiB
Newer Older
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
//
// SPDX-License-Identifier: MIT

import React, { Component } from 'react';
import { defaultAccount$ } from '@parity/light.js';
import { fromWei, toWei } from '@parity/api/lib/util/wei';
import { Header } from 'light-ui';
import { inject, observer } from 'mobx-react';
Amaury Martiny's avatar
Amaury Martiny committed
import light from 'light-hoc';
import { Link } from 'react-router-dom';

import TokenBalance from '../TokenBalance';

Amaury Martiny's avatar
Amaury Martiny committed
const MAX_GAS_PRICE = 40; // In Gwei
const MIN_GAS_PRICE = 3; // Safelow gas price from GasStation, in Gwei

@light({
  defaultAccount: defaultAccount$
})
@inject('sendStore')
@observer
class Send extends Component {
  state = {
    amount: 0.01, // In Ether or in token
Amaury Martiny's avatar
Amaury Martiny committed
    gasPrice: 4, // in Gwei
    to: '0x00Ae02834e91810B223E54ce3f9B7875258a1747'
  };

  handleChangeAmount = ({ target: { value } }) =>
    this.setState({ amount: value });

Amaury Martiny's avatar
Amaury Martiny committed
  handleChangeGasPrice = ({ target: { value } }) =>
    this.setState({ gasPrice: value });
Amaury Martiny's avatar
Amaury Martiny committed
  handleChangeTo = ({ target: { value } }) => {
    this.setState({ to: value }, () => {
      // Estimate the gas to this address.
      this.props.sendStore.estimateGas(this.state);
    });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { defaultAccount, history, sendStore } = this.props;
Amaury Martiny's avatar
Amaury Martiny committed
    const { amount, gasPrice, to } = this.state;

    // Post a request to the transaction. There is a next step to sign this
    // request.
    sendStore.postTx({
      from: defaultAccount,
Amaury Martiny's avatar
Amaury Martiny committed
      gasPrice: toWei(gasPrice, 'shannon'), // shannon == gwei
      to,
      value: toWei(amount)
    });

    history.push('/send/signer');
  };

  render () {
    const {
Amaury Martiny's avatar
Amaury Martiny committed
      sendStore: { estimated, token }
    } = this.props;
Amaury Martiny's avatar
Amaury Martiny committed
    const { amount, gasPrice, to } = this.state;
Amaury Martiny's avatar
Amaury Martiny committed
      <div>
        <Header
          left={
Amaury Martiny's avatar
Amaury Martiny committed
            <Link to='/tokens' className='icon -close'>
              Close
            </Link>
          }
          title={<h1>Send {token.name}</h1>}
        />

Amaury Martiny's avatar
Amaury Martiny committed
        <div className='window_content'>
          <div className='box -padded'>
            <div className='box -card'>
              <TokenBalance token={token} />
              <div className='box -card-drawer'>
                <form className='send-form' onSubmit={this.handleSubmit}>
                  <fieldset className='form_fields'>
                    <div className='form_field'>
                      <label>Amount</label>
                      <input
                        className='form_field_amount'
                        onChange={this.handleChangeAmount}
                        required
                        type='number'
                        value={amount}
                      />
                      <nav className='form-field_nav'>
                        <button className='button -utility' type='button'>
                          Max
                        </button>
                      </nav>
                    </div>
                    <div className='form_field'>
                      <label>To</label>
                      <textarea
                        className='-sm'
                        onChange={this.handleChangeTo}
                        required
                        type='text'
                        placeholder='Recipient address'
                        value={to}
                      />
                    </div>
                    <div className='form_field -range'>
                      <label>Gas</label>
                      <input
Amaury Martiny's avatar
Amaury Martiny committed
                        max={MAX_GAS_PRICE}
                        min={MIN_GAS_PRICE}
                        onChange={this.handleChangeGasPrice}
Amaury Martiny's avatar
Amaury Martiny committed
                        required
Amaury Martiny's avatar
Amaury Martiny committed
                        step={0.1}
Amaury Martiny's avatar
Amaury Martiny committed
                        type='range'
Amaury Martiny's avatar
Amaury Martiny committed
                        value={gasPrice}
Amaury Martiny's avatar
Amaury Martiny committed
                      />
                      <nav className='range-nav'>
                        <span className='range-nav_label'>Cheap</span>
Amaury Martiny's avatar
Amaury Martiny committed
                        <span className='range-nav_value'>
                          {fromWei(
Amaury Martiny's avatar
Amaury Martiny committed
                            toWei(gasPrice, 'shannon').mul(estimated)
Amaury Martiny's avatar
Amaury Martiny committed
                          ).toFixed(6)}{' '}
                          ETH
                        </span>
Amaury Martiny's avatar
Amaury Martiny committed
                        <span className='range-nav_label'>Fast</span>
                      </nav>
                    </div>
                  </fieldset>
                  <nav className='form-nav'>
                    <button className='button'>Send</button>
                  </nav>
                </form>
Amaury Martiny's avatar
Amaury Martiny committed
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default Send;