A Metamask fork with Infura removed and default networks editable
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ciphermask/ui/app/components/send-token/index.js

314 lines
8.4 KiB

const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
const ethUtil = require('ethereumjs-util')
const classnames = require('classnames')
const inherits = require('util').inherits
const actions = require('../../actions')
const selectors = require('../../selectors')
// const BalanceComponent = require('./balance-component')
const Identicon = require('../identicon')
const TokenBalance = require('../token-balance')
const CurrencyToggle = require('../send/currency-toggle')
const GasTooltip = require('../send/gas-tooltip')
const GasFeeDisplay = require('../send/gas-fee-display')
module.exports = connect(mapStateToProps, mapDispatchToProps)(SendTokenScreen)
function mapStateToProps (state) {
// const sidebarOpen = state.appState.sidebarOpen
const identities = state.metamask.identities
const addressBook = state.metamask.addressBook
const conversionRate = state.metamask.conversionRate
const currentBlockGasLimit = state.metamask.currentBlockGasLimit
const accounts = state.metamask.accounts
// const network = state.metamask.network
const selectedTokenAddress = state.metamask.selectedTokenAddress
const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
// const checksumAddress = selectedAddress && ethUtil.toChecksumAddress(selectedAddress)
// const identity = identities[selectedAddress]
return {
// sidebarOpen,
selectedAddress,
// checksumAddress,
selectedTokenAddress,
identities,
addressBook,
conversionRate,
currentBlockGasLimit,
selectedToken: selectors.getSelectedToken(state),
// selectedToken: selectors.getSelectedToken(state),
// identity,
// network,
}
}
function mapDispatchToProps (dispatch) {
return {
backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
// showSidebar: () => { dispatch(actions.showSidebar()) },
// hideSidebar: () => { dispatch(actions.hideSidebar()) },
// showModal: (payload) => { dispatch(actions.showModal(payload)) },
// showSendPage: () => { dispatch(actions.showSendPage()) },
// showSendTokenPage: () => { dispatch(actions.showSendTokenPage()) },
}
}
inherits(SendTokenScreen, Component)
function SendTokenScreen () {
Component.call(this)
this.state = {
to: '',
amount: null,
selectedCurrency: 'USD',
isGasTooltipOpen: false,
gasPrice: '0x5d21dba00',
gasLimit: '0x7b0d',
errors: {},
}
}
SendTokenScreen.prototype.validate = function () {
const {
to,
amount,
gasPrice: hexGasPrice,
gasLimit: hexGasLimit,
} = this.state
const gasPrice = parseInt(hexGasPrice, 16)
const gasLimit = parseInt(hexGasLimit, 16) / 1000000000
if (to && amount && gasPrice && gasLimit) {
return {
isValid: true,
errors: {},
}
}
const errors = {
to: !to ? 'Required' : null,
amount: !Number(amount) ? 'Required' : null,
gasPrice: !gasPrice ? 'Gas Price Required' : null,
gasLimit: !gasLimit ? 'Gas Limit Required' : null,
}
return {
isValid: false,
errors,
}
}
SendTokenScreen.prototype.submit = function () {
// const {
// to,
// amount,
// selectedCurrency,
// isGasTooltipOpen,
// gasPrice,
// gasLimit,
// } = this.state
const { isValid, errors } = this.validate()
if (!isValid) {
return this.setState({ errors })
}
}
SendTokenScreen.prototype.renderToAddressInput = function () {
const {
identities,
addressBook,
} = this.props
const {
to,
errors: { to: errorMessage },
} = this.state
return h('div', {
className: classnames('send-screen-input-wrapper', {
'send-screen-input-wrapper--error': errorMessage,
}),
}, [
h('div', ['To:']),
h('input.large-input.send-screen-input', {
name: 'address',
list: 'addresses',
placeholder: 'Address',
value: to,
onChange: e => this.setState({
to: e.target.value,
errors: {},
}),
}),
h('datalist#addresses', [
// Corresponds to the addresses owned.
Object.entries(identities).map(([key, { address, name }]) => {
return h('option', {
value: address,
label: name,
key: address,
})
}),
addressBook.map(({ address, name }) => {
return h('option', {
value: address,
label: name,
key: address,
})
}),
]),
h('div.send-screen-input-wrapper__error-message', [ errorMessage ]),
])
}
SendTokenScreen.prototype.renderAmountInput = function () {
const {
selectedCurrency,
amount,
errors: { amount: errorMessage },
} = this.state
const {
selectedToken: {symbol},
} = this.props
return h('div.send-screen-input-wrapper', {
className: classnames('send-screen-input-wrapper', {
'send-screen-input-wrapper--error': errorMessage,
}),
}, [
h('div.send-screen-amount-labels', [
h('span', ['Amount']),
h(CurrencyToggle, {
currentCurrency: selectedCurrency,
currencies: [ symbol, 'USD' ],
onClick: currency => this.setState({ selectedCurrency: currency }),
}),
]),
h('input.large-input.send-screen-input', {
placeholder: `0 ${symbol}`,
type: 'number',
value: amount,
onChange: e => this.setState({
amount: e.target.value,
errors: {},
}),
}),
h('div.send-screen-input-wrapper__error-message', [ errorMessage ]),
])
}
SendTokenScreen.prototype.renderGasInput = function () {
const {
isGasTooltipOpen,
gasPrice,
gasLimit,
selectedCurrency,
errors: {
gasPrice: gasPriceErrorMessage,
gasLimit: gasLimitErrorMessage,
},
} = this.state
const {
conversionRate,
currentBlockGasLimit,
} = this.props
return h('div.send-screen-input-wrapper', {
className: classnames('send-screen-input-wrapper', {
'send-screen-input-wrapper--error': gasPriceErrorMessage || gasLimitErrorMessage,
}),
}, [
isGasTooltipOpen && h(GasTooltip, {
className: 'send-tooltip',
gasPrice,
gasLimit,
onClose: () => this.setState({ isGasTooltipOpen: false }),
onFeeChange: ({ gasLimit, gasPrice }) => {
this.setState({ gasLimit, gasPrice, errors: {} })
},
}),
h('div.send-screen-gas-labels', {}, [
h('span', [ h('i.fa.fa-bolt'), 'Gas fee:']),
h('span', ['What\'s this?']),
]),
h('div.large-input.send-screen-gas-input', [
h(GasFeeDisplay, {
conversionRate,
gasPrice,
currentCurrency: selectedCurrency,
gas: gasLimit,
blockGasLimit: currentBlockGasLimit,
}),
h(
'div.send-screen-gas-input-customize',
{ onClick: () => this.setState({ isGasTooltipOpen: !isGasTooltipOpen }) },
['Customize']
),
]),
h('div.send-screen-input-wrapper__error-message', [
gasPriceErrorMessage || gasLimitErrorMessage,
]),
])
}
SendTokenScreen.prototype.renderMemoInput = function () {
return h('div.send-screen-input-wrapper', [
h('div', {}, ['Transaction memo (optional)']),
h(
'input.large-input.send-screen-input',
{ onChange: e => this.setState({ memo: e.target.value }) }
),
])
}
SendTokenScreen.prototype.renderButtons = function () {
const { selectedAddress, backToAccountDetail } = this.props
return h('div.send-token__button-group', [
h('button.send-token__button-next.btn-secondary', {
onClick: () => this.submit(),
}, ['Next']),
h('button.send-token__button-cancel.btn-tertiary', {
onClick: () => backToAccountDetail(selectedAddress),
}, ['Cancel']),
])
}
SendTokenScreen.prototype.render = function () {
const {
selectedTokenAddress,
selectedToken,
} = this.props
return h('div.send-token', [
h('div.send-token__content', [
h(Identicon, {
diameter: 75,
address: selectedTokenAddress,
}),
h('div.send-token__title', ['Send Tokens']),
h('div.send-token__description', ['Send Tokens to anyone with an Ethereum account']),
h('div.send-token__balance-text', ['Your Token Balance is:']),
h('div.send-token__token-balance', [
h(TokenBalance, { token: selectedToken, balanceOnly: true }),
]),
h('div.send-token__token-symbol', [selectedToken.symbol]),
this.renderToAddressInput(),
this.renderAmountInput(),
this.renderGasInput(),
this.renderMemoInput(),
]),
this.renderButtons(),
])
}