aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/scripts/lib/id-management.js7
-rw-r--r--ui/app/components/pending-tx-details.js2
-rw-r--r--ui/app/components/range-slider.js63
-rw-r--r--ui/app/send.js146
4 files changed, 185 insertions, 33 deletions
diff --git a/app/scripts/lib/id-management.js b/app/scripts/lib/id-management.js
index e250943a0..299998cee 100644
--- a/app/scripts/lib/id-management.js
+++ b/app/scripts/lib/id-management.js
@@ -7,6 +7,7 @@
*/
const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
const Transaction = require('ethereumjs-tx')
module.exports = IdManagement
@@ -24,7 +25,13 @@ function IdManagement (opts) {
}
this.signTx = function (txParams) {
+ // calculate gas with custom gas multiplier
+ var gasMultiplier = txParams.gasMultiplier || 1
+ delete txParams.gasMultiplier
+ var gasPrice = parseFloat(new BN(ethUtil.stripHexPrefix(txParams.gasPrice), 16).toString()) * gasMultiplier
+ txParams.gasPrice = ethUtil.intToHex(parseInt(gasPrice))
// normalize values
+
txParams.to = ethUtil.addHexPrefix(txParams.to)
txParams.from = ethUtil.addHexPrefix(txParams.from)
txParams.value = ethUtil.addHexPrefix(txParams.value)
diff --git a/ui/app/components/pending-tx-details.js b/ui/app/components/pending-tx-details.js
index d8e8524bf..7fa3d6ddd 100644
--- a/ui/app/components/pending-tx-details.js
+++ b/ui/app/components/pending-tx-details.js
@@ -29,8 +29,10 @@ PTXP.render = function () {
var account = props.accounts[address]
var balance = account ? account.balance : '0x0'
+ var gasMultiplier = txParams.gasMultiplier
var gasCost = new BN(ethUtil.stripHexPrefix(txParams.gas || txData.estimatedGas), 16)
var gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice || '0x4a817c800'), 16)
+ gasPrice = new BN(parseFloat(gasPrice.toString()) * gasMultiplier)
var txFee = gasCost.mul(gasPrice)
var txValue = new BN(ethUtil.stripHexPrefix(txParams.value || '0x0'), 16)
var maxCost = txValue.add(txFee)
diff --git a/ui/app/components/range-slider.js b/ui/app/components/range-slider.js
new file mode 100644
index 000000000..6ca6e434e
--- /dev/null
+++ b/ui/app/components/range-slider.js
@@ -0,0 +1,63 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = RangeSlider
+
+inherits(RangeSlider, Component)
+function RangeSlider () {
+ Component.call(this)
+}
+
+RangeSlider.prototype.render = function () {
+ const props = this.props
+ const onChange = props.onChange || function () {}
+ const name = props.name
+ const {
+ min = 0,
+ max = 100,
+ increment = 1,
+ defaultValue = 50,
+ mirrorInput = false,
+ } = this.props.options
+ const {container, input, range} = props.style
+
+ return (
+ h('.flex-row', {
+ style: container,
+ }, [
+ h('input', {
+ type: 'range',
+ name: name,
+ min: min,
+ max: max,
+ step: increment,
+ style: range,
+ defaultValue: defaultValue,
+ onChange: mirrorInput ? this.mirrorInputs.bind(this, name) : onChange,
+ }),
+
+ // Mirrored input for range
+ mirrorInput ? h('input.large-input', {
+ type: 'number',
+ name: `${name}Mirror`,
+ min: min,
+ max: max,
+ defaultValue: defaultValue,
+ step: increment,
+ style: input,
+ onChange: this.mirrorInputs.bind(this, `${name}Mirror`),
+ }) : null,
+ ])
+ )
+}
+
+RangeSlider.prototype.mirrorInputs = function (active) {
+ var range = document.querySelector(`input[name="${this.props.name}"]`)
+ var inputMirror = document.querySelector(`input[name="${this.props.name}Mirror"]`)
+ if (active === this.props.name) {
+ inputMirror.value = range.value
+ } else {
+ range.value = inputMirror.value
+ }
+}
diff --git a/ui/app/send.js b/ui/app/send.js
index 009866cf7..d10c658e3 100644
--- a/ui/app/send.js
+++ b/ui/app/send.js
@@ -9,7 +9,8 @@ const numericBalance = require('./util').numericBalance
const addressSummary = require('./util').addressSummary
const EthBalance = require('./components/eth-balance')
const ethUtil = require('ethereumjs-util')
-
+const RangeSlider = require('./components/range-slider')
+const Tooltip = require('./components/tooltip')
module.exports = connect(mapStateToProps)(SendTransactionScreen)
function mapStateToProps (state) {
@@ -50,7 +51,7 @@ SendTransactionScreen.prototype.render = function () {
// Sender Profile
//
- h('.account-data-subsection.flex-column.flex-grow', {
+ h('.account-data-subsection.flex-row.flex-grow', {
style: {
margin: '0 20px',
},
@@ -59,10 +60,9 @@ SendTransactionScreen.prototype.render = function () {
// header - identicon + nav
h('.flex-row.flex-space-between', {
style: {
- marginTop: 28,
+ marginTop: '15px',
},
}, [
-
// back button
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
onClick: this.back.bind(this),
@@ -77,42 +77,53 @@ SendTransactionScreen.prototype.render = function () {
]),
// invisible place holder
- h('i.fa.fa-users.fa-lg.invisible'),
+ h('i.fa.fa-users.fa-lg.invisible', {
+ style: {
+ marginTop: '28px',
+ },
+ }),
]),
// account label
- h('h2.font-medium.color-forest.flex-center', {
- style: {
- paddingTop: 8,
- marginBottom: 8,
- },
- }, identity && identity.name),
- // address and getter actions
- h('.flex-row.flex-center', {
+ h('.flex-column', {
style: {
- marginBottom: 8,
+ marginTop: '10px',
+ alignItems: 'flex-start',
},
}, [
+ h('h2.font-medium.color-forest.flex-center', {
+ style: {
+ paddingTop: '8px',
+ marginBottom: '8px',
+ },
+ }, identity && identity.name),
- h('div', {
+ // address and getter actions
+ h('.flex-row.flex-center', {
style: {
- lineHeight: '16px',
+ marginBottom: '8px',
},
- }, addressSummary(address)),
+ }, [
- ]),
+ h('div', {
+ style: {
+ lineHeight: '16px',
+ },
+ }, addressSummary(address)),
+
+ ]),
- // balance
- h('.flex-row.flex-center', [
+ // balance
+ h('.flex-row.flex-center', [
- h(EthBalance, {
- value: account && account.balance,
- }),
+ h(EthBalance, {
+ value: account && account.balance,
+ }),
+ ]),
]),
-
]),
//
@@ -123,8 +134,8 @@ SendTransactionScreen.prototype.render = function () {
style: {
background: '#EBEBEB',
color: '#AEAEAE',
- marginTop: 32,
- marginBottom: 16,
+ marginTop: '15px',
+ marginBottom: '16px',
},
}, [
'Send Transaction',
@@ -152,7 +163,7 @@ SendTransactionScreen.prototype.render = function () {
placeholder: 'Amount',
type: 'number',
style: {
- marginRight: 6,
+ marginRight: '6px',
},
dataset: {
persistentFormId: 'tx-amount',
@@ -171,20 +182,19 @@ SendTransactionScreen.prototype.render = function () {
//
// Optional Fields
//
-
h('h3.flex-center.text-transform-uppercase', {
style: {
background: '#EBEBEB',
color: '#AEAEAE',
- marginTop: 16,
- marginBottom: 16,
+ marginTop: '16px',
+ marginBottom: '16px',
},
}, [
'Transactional Data (optional)',
]),
// 'data' field
- h('section.flex-row.flex-center', [
+ h('section.flex-column.flex-center', [
h('input.large-input', {
name: 'txData',
placeholder: '0x01234',
@@ -197,6 +207,75 @@ SendTransactionScreen.prototype.render = function () {
},
}),
]),
+ // custom gas field
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: '5px',
+ },
+ }, [
+ 'Transaction Fee (optional)',
+ h(Tooltip, {
+ title: `
+ This is used to set the transactions
+ gas price. seting it to 100% will use
+ the full recomend value.
+ `,
+ }, [
+ h('i.fa.fa-question-circle', {
+ style: {
+ marginLeft: '5px',
+ },
+ }),
+ ]),
+ ]),
+
+ h('section.flex-column.flex-center', [
+ h('.flex-row', [
+ h(RangeSlider, {
+ name: 'gasInput',
+ options: {
+ mirrorInput: true,
+ defaultValue: 100,
+ min: 80,
+ max: 220,
+ },
+ style: {
+ container: {
+ marginBottom: '16px',
+ },
+ range: {
+ width: '68vw',
+ },
+ input: {
+ width: '5em',
+ marginLeft: '5px',
+ },
+ },
+ }),
+
+ h('div', {
+ style: {
+ fontSize: '12px',
+ paddingTop: '8px',
+ paddingLeft: '5px',
+ },
+ }, '%'),
+ ]),
+ h('.flex-row', {
+ style: {
+ justifyContent: 'space-between',
+ width: '243px',
+ position: 'relative',
+ fontSize: '12px',
+ right: '42px',
+ bottom: '30px',
+ },
+ }, [
+ h('span', 'Cheaper'), h('span', 'Faster'),
+ ]),
+ ]),
])
)
}
@@ -211,11 +290,12 @@ SendTransactionScreen.prototype.back = function () {
this.props.dispatch(actions.backToAccountDetail(address))
}
-SendTransactionScreen.prototype.onSubmit = function () {
+SendTransactionScreen.prototype.onSubmit = function (gasPrice) {
const recipient = document.querySelector('input[name="address"]').value
const input = document.querySelector('input[name="amount"]').value
const value = util.normalizeEthStringToWei(input)
const txData = document.querySelector('input[name="txData"]').value
+ const gasMultiplier = document.querySelector('input[name="gasInput"]').value
const balance = this.props.balance
let message
@@ -243,6 +323,6 @@ SendTransactionScreen.prototype.onSubmit = function () {
if (recipient) txParams.to = ethUtil.addHexPrefix(recipient)
if (txData) txParams.data = txData
-
+ txParams.gasMultiplier = gasMultiplier * 0.01
this.props.dispatch(actions.signTx(txParams))
}