move confirm dialog requirement out of universal-dapp logic

pull/3094/head
Iuri Matias 6 years ago committed by yann300
parent 416f34fde0
commit ea3e37996f
  1. 122
      src/app/tabs/run-tab.js
  2. 65
      src/recorder.js
  3. 68
      src/universal-dapp-ui.js
  4. 77
      src/universal-dapp.js

@ -7,6 +7,7 @@ var csjs = require('csjs-inject')
var txExecution = remixLib.execution.txExecution var txExecution = remixLib.execution.txExecution
var txFormat = remixLib.execution.txFormat var txFormat = remixLib.execution.txFormat
var txHelper = remixLib.execution.txHelper var txHelper = remixLib.execution.txHelper
var typeConversion = remixLib.execution.typeConversion
var EventManager = require('../../lib/events') var EventManager = require('../../lib/events')
var globlalRegistry = require('../../global/registry') var globlalRegistry = require('../../global/registry')
var helper = require('../../lib/helper.js') var helper = require('../../lib/helper.js')
@ -24,6 +25,8 @@ var modalDialog = require('../ui/modaldialog')
var CompilerAbstract = require('../compiler/compiler-abstract') var CompilerAbstract = require('../compiler/compiler-abstract')
var tootip = require('../ui/tooltip') var tootip = require('../ui/tooltip')
var confirmDialog = require('../execution/confirmDialog')
function runTab (opts, localRegistry) { function runTab (opts, localRegistry) {
/* ------------------------- /* -------------------------
VARIABLES VARIABLES
@ -394,7 +397,63 @@ function contractDropdown (events, self) {
data.linkReferences = selectedContract.contract.object.evm.bytecode.linkReferences data.linkReferences = selectedContract.contract.object.evm.bytecode.linkReferences
data.contractABI = selectedContract.contract.object.abi data.contractABI = selectedContract.contract.object.abi
} }
self._deps.udapp.createContract(data, (error, txResult) => { self._deps.udapp.createContract(data,
(network, tx, gasEstimation, continueTxExecution, cancelCb) => {
if (network.name !== 'Main') {
return continueTxExecution(null)
}
var amount = executionContext.web3().fromWei(typeConversion.toInt(tx.value), 'ether')
var content = confirmDialog(tx, amount, gasEstimation, self,
(gasPrice, cb) => {
let txFeeText, priceStatus
// TODO: this try catch feels like an anti pattern, can/should be
// removed, but for now keeping the original logic
try {
var fee = executionContext.web3().toBigNumber(tx.gas).mul(executionContext.web3().toBigNumber(executionContext.web3().toWei(gasPrice.toString(10), 'gwei')))
txFeeText = ' ' + executionContext.web3().fromWei(fee.toString(10), 'ether') + ' Ether'
priceStatus = true
} catch (e) {
txFeeText = ' Please fix this issue before sending any transaction. ' + e.message
priceStatus = false
}
cb(txFeeText, priceStatus)
},
(cb) => {
executionContext.web3().eth.getGasPrice((error, gasPrice) => {
var warnMessage = ' Please fix this issue before sending any transaction. '
if (error) {
return cb('Unable to retrieve the current network gas price.' + warnMessage + error)
}
try {
var gasPriceValue = executionContext.web3().fromWei(gasPrice.toString(10), 'gwei')
cb(null, gasPriceValue)
} catch (e) {
cb(warnMessage + e.message, null, false)
}
})
}
)
modalDialog('Confirm transaction', content,
{ label: 'Confirm',
fn: () => {
self._deps.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked)
// TODO: check if this is check is still valid given the refactor
if (!content.gasPriceStatus) {
cancelCb('Given gas price is not correct')
} else {
var gasPrice = executionContext.web3().toWei(content.querySelector('#gasprice').value, 'gwei')
continueTxExecution(gasPrice)
}
}}, {
label: 'Cancel',
fn: () => {
return cancelCb('Transaction canceled by user.')
}
})
},
(error, txResult) => {
if (!error) { if (!error) {
var isVM = executionContext.isVM() var isVM = executionContext.isVM()
if (isVM) { if (isVM) {
@ -415,7 +474,8 @@ function contractDropdown (events, self) {
} else { } else {
self._deps.logCallback(`creation of ${selectedContract.name} errored: ${error}`) self._deps.logCallback(`creation of ${selectedContract.name} errored: ${error}`)
} }
}) }
)
} }
// DEPLOY INSTANCE // DEPLOY INSTANCE
@ -439,7 +499,63 @@ function contractDropdown (events, self) {
self._deps.logCallback(msg) self._deps.logCallback(msg)
}, (data, runTxCallback) => { }, (data, runTxCallback) => {
// called for libraries deployment // called for libraries deployment
self._deps.udapp.runTx(data, runTxCallback) self._deps.udapp.runTx(data,
(network, tx, gasEstimation, continueTxExecution, cancelCb) => {
if (network.name !== 'Main') {
return continueTxExecution(null)
}
var amount = executionContext.web3().fromWei(typeConversion.toInt(tx.value), 'ether')
var content = confirmDialog(tx, amount, gasEstimation, self,
(gasPrice, cb) => {
let txFeeText, priceStatus
// TODO: this try catch feels like an anti pattern, can/should be
// removed, but for now keeping the original logic
try {
var fee = executionContext.web3().toBigNumber(tx.gas).mul(executionContext.web3().toBigNumber(executionContext.web3().toWei(gasPrice.toString(10), 'gwei')))
txFeeText = ' ' + executionContext.web3().fromWei(fee.toString(10), 'ether') + ' Ether'
priceStatus = true
} catch (e) {
txFeeText = ' Please fix this issue before sending any transaction. ' + e.message
priceStatus = false
}
cb(txFeeText, priceStatus)
},
(cb) => {
executionContext.web3().eth.getGasPrice((error, gasPrice) => {
var warnMessage = ' Please fix this issue before sending any transaction. '
if (error) {
return cb('Unable to retrieve the current network gas price.' + warnMessage + error)
}
try {
var gasPriceValue = executionContext.web3().fromWei(gasPrice.toString(10), 'gwei')
cb(null, gasPriceValue)
} catch (e) {
cb(warnMessage + e.message, null, false)
}
})
}
)
modalDialog('Confirm transaction', content,
{ label: 'Confirm',
fn: () => {
self._deps.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked)
// TODO: check if this is check is still valid given the refactor
if (!content.gasPriceStatus) {
cancelCb('Given gas price is not correct')
} else {
var gasPrice = executionContext.web3().toWei(content.querySelector('#gasprice').value, 'gwei')
continueTxExecution(gasPrice)
}
}}, {
label: 'Cancel',
fn: () => {
return cancelCb('Transaction canceled by user.')
}
})
},
runTxCallback)
}) })
} else { } else {
if (Object.keys(selectedContract.contract.object.evm.bytecode.linkReferences).length) self._deps.logCallback(`linking ${JSON.stringify(selectedContract.contract.object.evm.bytecode.linkReferences, null, '\t')} using ${JSON.stringify(contractMetadata.linkReferences, null, '\t')}`) if (Object.keys(selectedContract.contract.object.evm.bytecode.linkReferences).length) self._deps.logCallback(`linking ${JSON.stringify(selectedContract.contract.object.evm.bytecode.linkReferences, null, '\t')} using ${JSON.stringify(contractMetadata.linkReferences, null, '\t')}`)

@ -4,9 +4,13 @@ var ethutil = require('ethereumjs-util')
var executionContext = require('./execution-context') var executionContext = require('./execution-context')
var format = remixLib.execution.txFormat var format = remixLib.execution.txFormat
var txHelper = remixLib.execution.txHelper var txHelper = remixLib.execution.txHelper
var typeConversion = remixLib.execution.typeConversion
var async = require('async') var async = require('async')
var modal = require('./app/ui/modal-dialog-custom') var modal = require('./app/ui/modal-dialog-custom')
var modalDialog = require('./app/ui/modaldialog')
var confirmDialog = require('./app/execution/confirmDialog')
/** /**
* Record transaction as long as the user create them. * Record transaction as long as the user create them.
* *
@ -238,7 +242,63 @@ class Recorder {
self.logCallBack(`(${index}) data: ${data.data}`) self.logCallBack(`(${index}) data: ${data.data}`)
record.data = { dataHex: data.data, funArgs: tx.record.parameters, funAbi: fnABI, contractBytecode: tx.record.bytecode, contractName: tx.record.contractName } record.data = { dataHex: data.data, funArgs: tx.record.parameters, funAbi: fnABI, contractBytecode: tx.record.bytecode, contractName: tx.record.contractName }
} }
udapp.runTx(record, function (err, txResult) { udapp.runTx(record,
(network, tx, gasEstimation, continueTxExecution, cancelCb) => {
if (network.name !== 'Main') {
return continueTxExecution(null)
}
var amount = executionContext.web3().fromWei(typeConversion.toInt(tx.value), 'ether')
var content = confirmDialog(tx, amount, gasEstimation, self,
(gasPrice, cb) => {
let txFeeText, priceStatus
// TODO: this try catch feels like an anti pattern, can/should be
// removed, but for now keeping the original logic
try {
var fee = executionContext.web3().toBigNumber(tx.gas).mul(executionContext.web3().toBigNumber(executionContext.web3().toWei(gasPrice.toString(10), 'gwei')))
txFeeText = ' ' + executionContext.web3().fromWei(fee.toString(10), 'ether') + ' Ether'
priceStatus = true
} catch (e) {
txFeeText = ' Please fix this issue before sending any transaction. ' + e.message
priceStatus = false
}
cb(txFeeText, priceStatus)
},
(cb) => {
executionContext.web3().eth.getGasPrice((error, gasPrice) => {
var warnMessage = ' Please fix this issue before sending any transaction. '
if (error) {
return cb('Unable to retrieve the current network gas price.' + warnMessage + error)
}
try {
var gasPriceValue = executionContext.web3().fromWei(gasPrice.toString(10), 'gwei')
cb(null, gasPriceValue)
} catch (e) {
cb(warnMessage + e.message, null, false)
}
})
}
)
modalDialog('Confirm transaction', content,
{ label: 'Confirm',
fn: () => {
udapp._deps.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked)
// TODO: check if this is check is still valid given the refactor
if (!content.gasPriceStatus) {
cancelCb('Given gas price is not correct')
} else {
var gasPrice = executionContext.web3().toWei(content.querySelector('#gasprice').value, 'gwei')
continueTxExecution(gasPrice)
}
}}, {
label: 'Cancel',
fn: () => {
return cancelCb('Transaction canceled by user.')
}
})
},
function (err, txResult) {
if (err) { if (err) {
console.error(err) console.error(err)
self.logCallBack(err + '. Execution failed at ' + index) self.logCallBack(err + '. Execution failed at ' + index)
@ -253,7 +313,8 @@ class Recorder {
} }
} }
cb(err) cb(err)
}) }
)
}, () => { self.setListen(true); self.clearAll() }) }, () => { self.setListen(true); self.clearAll() })
} }
} }

@ -7,6 +7,13 @@ var helper = require('./lib/helper')
var copyToClipboard = require('./app/ui/copy-to-clipboard') var copyToClipboard = require('./app/ui/copy-to-clipboard')
var css = require('./universal-dapp-styles') var css = require('./universal-dapp-styles')
var MultiParamManager = require('./multiParamManager') var MultiParamManager = require('./multiParamManager')
var remixLib = require('remix-lib')
var typeConversion = remixLib.execution.typeConversion
var executionContext = require('./execution-context')
var modalDialog = require('./app/ui/modaldialog')
var confirmDialog = require('./app/execution/confirmDialog')
function UniversalDAppUI (udapp, opts = {}) { function UniversalDAppUI (udapp, opts = {}) {
this.udapp = udapp this.udapp = udapp
@ -90,10 +97,67 @@ UniversalDAppUI.prototype.getCallButton = function (args) {
var outputOverride = yo`<div class=${css.value}></div>` // show return value var outputOverride = yo`<div class=${css.value}></div>` // show return value
function clickButton (valArr, inputsValues) { function clickButton (valArr, inputsValues) {
self.udapp.call(true, args, inputsValues, lookupOnly, (decoded) => { self.udapp.call(true, args, inputsValues, lookupOnly,
(network, tx, gasEstimation, continueTxExecution, cancelCb) => {
if (network.name !== 'Main') {
return continueTxExecution(null)
}
var amount = executionContext.web3().fromWei(typeConversion.toInt(tx.value), 'ether')
var content = confirmDialog(tx, amount, gasEstimation, self,
(gasPrice, cb) => {
let txFeeText, priceStatus
// TODO: this try catch feels like an anti pattern, can/should be
// removed, but for now keeping the original logic
try {
var fee = executionContext.web3().toBigNumber(tx.gas).mul(executionContext.web3().toBigNumber(executionContext.web3().toWei(gasPrice.toString(10), 'gwei')))
txFeeText = ' ' + executionContext.web3().fromWei(fee.toString(10), 'ether') + ' Ether'
priceStatus = true
} catch (e) {
txFeeText = ' Please fix this issue before sending any transaction. ' + e.message
priceStatus = false
}
cb(txFeeText, priceStatus)
},
(cb) => {
executionContext.web3().eth.getGasPrice((error, gasPrice) => {
var warnMessage = ' Please fix this issue before sending any transaction. '
if (error) {
return cb('Unable to retrieve the current network gas price.' + warnMessage + error)
}
try {
var gasPriceValue = executionContext.web3().fromWei(gasPrice.toString(10), 'gwei')
cb(null, gasPriceValue)
} catch (e) {
cb(warnMessage + e.message, null, false)
}
})
}
)
modalDialog('Confirm transaction', content,
{ label: 'Confirm',
fn: () => {
self._deps.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked)
// TODO: check if this is check is still valid given the refactor
if (!content.gasPriceStatus) {
cancelCb('Given gas price is not correct')
} else {
var gasPrice = executionContext.web3().toWei(content.querySelector('#gasprice').value, 'gwei')
continueTxExecution(gasPrice)
}
}}, {
label: 'Cancel',
fn: () => {
return cancelCb('Transaction canceled by user.')
}
})
},
(decoded) => {
outputOverride.innerHTML = '' outputOverride.innerHTML = ''
outputOverride.appendChild(decoded) outputOverride.appendChild(decoded)
}) }
)
} }
var multiParamManager = new MultiParamManager(lookupOnly, args.funABI, (valArray, inputsValues, domEl) => { var multiParamManager = new MultiParamManager(lookupOnly, args.funABI, (valArray, inputsValues, domEl) => {

@ -13,13 +13,10 @@ var txExecution = remixLib.execution.txExecution
var txFormat = remixLib.execution.txFormat var txFormat = remixLib.execution.txFormat
var txHelper = remixLib.execution.txHelper var txHelper = remixLib.execution.txHelper
var executionContext = require('./execution-context') var executionContext = require('./execution-context')
var modalCustom = require('./app/ui/modal-dialog-custom')
var globalRegistry = require('./global/registry') var globalRegistry = require('./global/registry')
var modalCustom = require('./app/ui/modal-dialog-custom')
var modalDialog = require('./app/ui/modaldialog') var modalDialog = require('./app/ui/modaldialog')
var typeConversion = remixLib.execution.typeConversion
var confirmDialog = require('./app/execution/confirmDialog')
var TreeView = require('./app/ui/TreeView') var TreeView = require('./app/ui/TreeView')
function decodeResponseToTreeView (response, fnabi) { function decodeResponseToTreeView (response, fnabi) {
@ -205,7 +202,7 @@ UniversalDApp.prototype.pendingTransactionsCount = function () {
return Object.keys(this.txRunner.pendingTxs).length return Object.keys(this.txRunner.pendingTxs).length
} }
UniversalDApp.prototype.call = function (isUserAction, args, value, lookupOnly, outputCb) { UniversalDApp.prototype.call = function (isUserAction, args, value, lookupOnly, confirmationCb, outputCb) {
const self = this const self = this
var logMsg var logMsg
if (isUserAction) { if (isUserAction) {
@ -225,7 +222,7 @@ UniversalDApp.prototype.call = function (isUserAction, args, value, lookupOnly,
} }
} }
if (args.funABI.type === 'fallback') data.dataHex = value if (args.funABI.type === 'fallback') data.dataHex = value
self.callFunction(args.address, data, args.funABI, (error, txResult) => { self.callFunction(args.address, data, args.funABI, confirmationCb, (error, txResult) => {
if (!error) { if (!error) {
var isVM = executionContext.isVM() var isVM = executionContext.isVM()
if (isVM) { if (isVM) {
@ -250,7 +247,7 @@ UniversalDApp.prototype.call = function (isUserAction, args, value, lookupOnly,
self._deps.logCallback(msg) self._deps.logCallback(msg)
}, (data, runTxCallback) => { }, (data, runTxCallback) => {
// called for libraries deployment // called for libraries deployment
self.runTx(data, runTxCallback) self.runTx(data, confirmationCb, runTxCallback)
}) })
} }
@ -260,8 +257,8 @@ UniversalDApp.prototype.call = function (isUserAction, args, value, lookupOnly,
* @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ). * @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ).
* @param {Function} callback - callback. * @param {Function} callback - callback.
*/ */
UniversalDApp.prototype.createContract = function (data, callback) { UniversalDApp.prototype.createContract = function (data, confirmationCb, callback) {
this.runTx({data: data, useCall: false}, (error, txResult) => { this.runTx({data: data, useCall: false}, confirmationCb, (error, txResult) => {
// see universaldapp.js line 660 => 700 to check possible values of txResult (error case) // see universaldapp.js line 660 => 700 to check possible values of txResult (error case)
callback(error, txResult) callback(error, txResult)
}) })
@ -275,8 +272,8 @@ UniversalDApp.prototype.createContract = function (data, callback) {
* @param {Object} funAbi - abi definition of the function to call. * @param {Object} funAbi - abi definition of the function to call.
* @param {Function} callback - callback. * @param {Function} callback - callback.
*/ */
UniversalDApp.prototype.callFunction = function (to, data, funAbi, callback) { UniversalDApp.prototype.callFunction = function (to, data, funAbi, confirmationCb, callback) {
this.runTx({to: to, data: data, useCall: funAbi.constant}, (error, txResult) => { this.runTx({to: to, data: data, useCall: funAbi.constant}, confirmationCb, (error, txResult) => {
// see universaldapp.js line 660 => 700 to check possible values of txResult (error case) // see universaldapp.js line 660 => 700 to check possible values of txResult (error case)
callback(error, txResult) callback(error, txResult)
}) })
@ -318,7 +315,7 @@ UniversalDApp.prototype.silentRunTx = function (tx, cb) {
cb) cb)
} }
UniversalDApp.prototype.runTx = function (args, cb) { UniversalDApp.prototype.runTx = function (args, confirmationCb, cb) {
const self = this const self = this
async.waterfall([ async.waterfall([
function getGasLimit (next) { function getGasLimit (next) {
@ -364,61 +361,7 @@ UniversalDApp.prototype.runTx = function (args, cb) {
var timestamp = Date.now() var timestamp = Date.now()
self.event.trigger('initiatingTransaction', [timestamp, tx, payLoad]) self.event.trigger('initiatingTransaction', [timestamp, tx, payLoad])
self.txRunner.rawRun(tx, self.txRunner.rawRun(tx, confirmationCb,
(network, tx, gasEstimation, continueTxExecution, cancelCb) => {
if (network.name !== 'Main') {
return continueTxExecution(null)
}
var amount = executionContext.web3().fromWei(typeConversion.toInt(tx.value), 'ether')
var content = confirmDialog(tx, amount, gasEstimation, self,
(gasPrice, cb) => {
let txFeeText, priceStatus
// TODO: this try catch feels like an anti pattern, can/should be
// removed, but for now keeping the original logic
try {
var fee = executionContext.web3().toBigNumber(tx.gas).mul(executionContext.web3().toBigNumber(executionContext.web3().toWei(gasPrice.toString(10), 'gwei')))
txFeeText = ' ' + executionContext.web3().fromWei(fee.toString(10), 'ether') + ' Ether'
priceStatus = true
} catch (e) {
txFeeText = ' Please fix this issue before sending any transaction. ' + e.message
priceStatus = false
}
cb(txFeeText, priceStatus)
},
(cb) => {
executionContext.web3().eth.getGasPrice((error, gasPrice) => {
var warnMessage = ' Please fix this issue before sending any transaction. '
if (error) {
return cb('Unable to retrieve the current network gas price.' + warnMessage + error)
}
try {
var gasPriceValue = executionContext.web3().fromWei(gasPrice.toString(10), 'gwei')
cb(null, gasPriceValue)
} catch (e) {
cb(warnMessage + e.message, null, false)
}
})
}
)
modalDialog('Confirm transaction', content,
{ label: 'Confirm',
fn: () => {
self._deps.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked)
// TODO: check if this is check is still valid given the refactor
if (!content.gasPriceStatus) {
cancelCb('Given gas price is not correct')
} else {
var gasPrice = executionContext.web3().toWei(content.querySelector('#gasprice').value, 'gwei')
continueTxExecution(gasPrice)
}
}}, {
label: 'Cancel',
fn: () => {
return cancelCb('Transaction canceled by user.')
}
})
},
(error, continueTxExecution, cancelCb) => { (error, continueTxExecution, cancelCb) => {
if (error) { if (error) {
var msg = typeof error !== 'string' ? error.message : error var msg = typeof error !== 'string' ? error.message : error

Loading…
Cancel
Save