diff --git a/src/app/panels/righthand-panel.js b/src/app/panels/righthand-panel.js
index b995c77d73..723339d585 100644
--- a/src/app/panels/righthand-panel.js
+++ b/src/app/panels/righthand-panel.js
@@ -11,8 +11,43 @@ const DraggableContent = require('../ui/draggableContent')
const styles = styleguide.chooser()
-module.exports = class RighthandPanel {
- constructor ({pluginManager, tabs}, localRegistry) {
+const css = csjs`
+ .righthandpanel {
+ display : flex;
+ flex-direction : column;
+ top : 0;
+ right : 0;
+ bottom : 0;
+ box-sizing : border-box;
+ overflow : hidden;
+ height : 100%;
+ }
+ .header {
+ height : 100%;
+ }
+ .dragbar {
+ position : absolute;
+ width : 0.5em;
+ top : 3em;
+ bottom : 0;
+ cursor : col-resize;
+ z-index : 999;
+ border-left : 2px solid ${styles.rightPanel.bar_Dragging};
+ }
+ .ghostbar {
+ width : 3px;
+ background-color : ${styles.rightPanel.bar_Ghost};
+ opacity : 0.5;
+ position : absolute;
+ cursor : col-resize;
+ z-index : 9999;
+ top : 0;
+ bottom : 0;
+ }
+`
+
+class RighthandPanel {
+ constructor (localRegistry) {
const self = this
self._components = {}
self._components.registry = localRegistry || globalRegistry
@@ -125,37 +160,4 @@ module.exports = class RighthandPanel {
}
}
-const css = csjs`
- .righthandpanel {
- display : flex;
- flex-direction : column;
- top : 0;
- right : 0;
- bottom : 0;
- box-sizing : border-box;
- overflow : hidden;
- height : 100%;
- }
- .header {
- height : 100%;
- }
- .dragbar {
- position : absolute;
- width : 0.5em;
- top : 3em;
- bottom : 0;
- cursor : col-resize;
- z-index : 999;
- border-left : 2px solid ${styles.rightPanel.bar_Dragging};
- }
- .ghostbar {
- width : 3px;
- background-color : ${styles.rightPanel.bar_Ghost};
- opacity : 0.5;
- position : absolute;
- cursor : col-resize;
- z-index : 9999;
- top : 0;
- bottom : 0;
- }
-`
+module.exports = RighthandPanel
diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js
index ae6129d33d..a7c1c5a9d1 100644
--- a/src/app/tabs/run-tab.js
+++ b/src/app/tabs/run-tab.js
@@ -1,32 +1,18 @@
'use strict'
var $ = require('jquery')
var yo = require('yo-yo')
-var remixLib = require('remix-lib')
-var ethJSUtil = require('ethereumjs-util')
var csjs = require('csjs-inject')
-var txExecution = remixLib.execution.txExecution
-var txFormat = remixLib.execution.txFormat
-var txHelper = remixLib.execution.txHelper
-var typeConversion = remixLib.execution.typeConversion
var EventManager = require('../../lib/events')
var globlalRegistry = require('../../global/registry')
var helper = require('../../lib/helper.js')
var executionContext = require('../../execution-context')
var modalDialogCustom = require('../ui/modal-dialog-custom')
-var copyToClipboard = require('../ui/copy-to-clipboard')
-const Buffer = require('safe-buffer').Buffer
-var Personal = require('web3-eth-personal')
var Card = require('../ui/card')
var Recorder = require('../../recorder')
-var addTooltip = require('../ui/tooltip')
var css = require('./styles/run-tab-styles')
-var MultiParamManager = require('../../multiParamManager')
-var modalDialog = require('../ui/modaldialog')
-var CompilerAbstract = require('../compiler/compiler-abstract')
-var tootip = require('../ui/tooltip')
-var confirmDialog = require('../execution/confirmDialog')
-var modalCustom = require('../ui/modal-dialog-custom')
+var settingsUI = require('./runTab/settings.js')
+var contractDropdownUI = require('./runTab/contractDropdown.js')
function runTab (opts, localRegistry) {
/* -------------------------
@@ -144,8 +130,8 @@ function runTab (opts, localRegistry) {
--------------------------- */
var el = yo`
- ${settings(container, self)}
- ${contractDropdown(self.event, self)}
+ ${settingsUI(container, self)}
+ ${contractDropdownUI(self.event, self)}
${recorderCard.render()}
${self._view.instanceContainer}
@@ -155,47 +141,6 @@ function runTab (opts, localRegistry) {
return { render () { return container } }
}
-var accountListCallId = 0
-var loadedAccounts = {}
-function fillAccountsList (container, self) {
- accountListCallId++
- (function (callid) {
- var txOrigin = container.querySelector('#txorigin')
- self._deps.udapp.getAccounts((err, accounts) => {
- if (accountListCallId > callid) return
- accountListCallId++
- if (err) { addTooltip(`Cannot get account list: ${err}`) }
- for (var loadedaddress in loadedAccounts) {
- if (accounts.indexOf(loadedaddress) === -1) {
- txOrigin.removeChild(txOrigin.querySelector('option[value="' + loadedaddress + '"]'))
- delete loadedAccounts[loadedaddress]
- }
- }
- for (var i in accounts) {
- var address = accounts[i]
- if (!loadedAccounts[address]) {
- txOrigin.appendChild(yo``)
- loadedAccounts[address] = 1
- }
- }
- txOrigin.setAttribute('value', accounts[0])
- })
- })(accountListCallId)
-}
-
-function updateAccountBalances (container, self) {
- var accounts = $(container.querySelector('#txorigin')).children('option')
- accounts.each(function (index, value) {
- (function (acc) {
- self._deps.udapp.getBalanceInEther(accounts[acc].value, function (err, res) {
- if (!err) {
- accounts[acc].innerText = helper.shortenAddress(accounts[acc].value, res)
- }
- })
- })(index)
- })
-}
-
/* ------------------------------------------------
RECORDER
------------------------------------------------ */
@@ -289,617 +234,5 @@ function makeRecorder (registry, runTabEvent, self) {
return { recordButton, runButton }
}
-/* ------------------------------------------------
- CONTRACT (deploy or access deployed)
------------------------------------------------- */
-
-function contractDropdown (events, self) {
- var instanceContainer = self._view.instanceContainer
- var instanceContainerTitle = self._view.instanceContainerTitle
- instanceContainer.appendChild(instanceContainerTitle)
- instanceContainer.appendChild(self._view.noInstancesText)
- var compFails = yo``
- var info = yo``
-
- var newlyCompiled = (success, data, source, compiler, compilerFullName) => {
- getContractNames(success, data, compiler, compilerFullName)
- if (success) {
- compFails.style.display = 'none'
- document.querySelector(`.${css.contractNames}`).classList.remove(css.contractNamesError)
- } else {
- compFails.style.display = 'block'
- document.querySelector(`.${css.contractNames}`).classList.add(css.contractNamesError)
- }
- }
-
- self._deps.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
- let compiler = new CompilerAbstract(languageVersion, data, source)
- newlyCompiled(true, data, source, compiler, languageVersion)
- })
-
- var deployAction = (value) => {
- self._view.createPanel.style.display = value
- self._view.orLabel.style.display = value
- }
-
- self._deps.fileManager.event.register('currentFileChanged', (currentFile) => {
- document.querySelector(`.${css.contractNames}`).classList.remove(css.contractNamesError)
- var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
- contractNames.innerHTML = ''
- if (/.(.abi)$/.exec(currentFile)) {
- deployAction('none')
- compFails.style.display = 'none'
- contractNames.appendChild(yo``)
- selectContractNames.setAttribute('disabled', true)
- } else if (/.(.sol)$/.exec(currentFile)) {
- deployAction('block')
- }
- })
-
- var atAddressButtonInput = yo``
- var selectContractNames = yo``
-
- function getSelectedContract () {
- var contract = selectContractNames.children[selectContractNames.selectedIndex]
- var contractName = contract.innerHTML
- var compiler = self._deps.compilersArtefacts['__last']
- if (!compiler) return null
-
- if (contractName) {
- return {
- name: contractName,
- contract: compiler.getContract(contractName),
- compiler
- }
- }
- return null
- }
-
- self._view.createPanel = yo``
- self._view.orLabel = yo`or
`
- var el = yo`
-
-
- ${selectContractNames} ${compFails} ${info}
-
-
- ${self._view.createPanel}
- ${self._view.orLabel}
-
-
-
- `
-
- function setInputParamsPlaceHolder () {
- self._view.createPanel.innerHTML = ''
- if (selectContractNames.selectedIndex >= 0 && selectContractNames.children.length > 0) {
- var selectedContract = getSelectedContract()
- var ctrabi = txHelper.getConstructorInterface(selectedContract.contract.object.abi)
- var ctrEVMbc = selectedContract.contract.object.evm.bytecode.object
- var createConstructorInstance = new MultiParamManager(0, ctrabi, (valArray, inputsValues) => {
- createInstance(inputsValues, selectedContract.compiler)
- }, txHelper.inputParametersDeclarationToString(ctrabi.inputs), 'Deploy', ctrEVMbc)
- self._view.createPanel.appendChild(createConstructorInstance.render())
- return
- } else {
- self._view.createPanel.innerHTML = 'No compiled contracts'
- }
- }
-
- selectContractNames.addEventListener('change', setInputParamsPlaceHolder)
-
- function createInstanceCallback (selectedContract, data) {
- self._deps.logCallback(`creation of ${selectedContract.name} pending...`)
- if (data) {
- data.contractName = selectedContract.name
- data.linkReferences = selectedContract.contract.object.evm.bytecode.linkReferences
- data.contractABI = selectedContract.contract.object.abi
- }
- 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, continueTxExecution, cancelCb) => {
- if (error) {
- var msg = typeof error !== 'string' ? error.message : error
- modalDialog('Gas estimation failed', yo`Gas estimation errored with the following message (see below).
- The transaction execution will likely fail. Do you want to force sending?
- ${msg}
-
`,
- {
- label: 'Send Transaction',
- fn: () => {
- continueTxExecution()
- }}, {
- label: 'Cancel Transaction',
- fn: () => {
- cancelCb()
- }
- })
- } else {
- continueTxExecution()
- }
- },
- function (okCb, cancelCb) {
- modalCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
- },
- (error, txResult) => {
- if (!error) {
- var isVM = executionContext.isVM()
- if (isVM) {
- var vmError = txExecution.checkVMError(txResult)
- if (vmError.error) {
- self._deps.logCallback(vmError.message)
- return
- }
- }
- if (txResult.result.status && txResult.result.status === '0x0') {
- self._deps.logCallback(`creation of ${selectedContract.name} errored: transaction execution failed`)
- return
- }
- var noInstancesText = self._view.noInstancesText
- if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
- var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress
- instanceContainer.appendChild(self._deps.udappUI.renderInstance(selectedContract.contract.object, address, selectContractNames.value))
- } else {
- self._deps.logCallback(`creation of ${selectedContract.name} errored: ${error}`)
- }
- }
- )
- }
-
- // DEPLOY INSTANCE
- function createInstance (args, compiler) {
- var selectedContract = getSelectedContract()
-
- if (selectedContract.contract.object.evm.bytecode.object.length === 0) {
- modalDialogCustom.alert('This contract may be abstract, not implement an abstract parent\'s methods completely or not invoke an inherited contract\'s constructor correctly.')
- return
- }
-
- var forceSend = () => {
- var constructor = txHelper.getConstructorInterface(selectedContract.contract.object.abi)
- self._deps.filePanel.compilerMetadata().deployMetadataOf(selectedContract.name, (error, contractMetadata) => {
- if (error) return self._deps.logCallback(`creation of ${selectedContract.name} errored: ` + error)
- if (!contractMetadata || (contractMetadata && contractMetadata.autoDeployLib)) {
- txFormat.buildData(selectedContract.name, selectedContract.contract.object, compiler.getContracts(), true, constructor, args, (error, data) => {
- if (error) return self._deps.logCallback(`creation of ${selectedContract.name} errored: ` + error)
- createInstanceCallback(selectedContract, data)
- }, (msg) => {
- self._deps.logCallback(msg)
- }, (data, runTxCallback) => {
- // called for libraries deployment
- 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.')
- }
- })
- },
- function (okCb, cancelCb) {
- modalCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
- },
- runTxCallback)
- })
- } 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')}`)
- txFormat.encodeConstructorCallAndLinkLibraries(selectedContract.contract.object, args, constructor, contractMetadata.linkReferences, selectedContract.contract.object.evm.bytecode.linkReferences, (error, data) => {
- if (error) return self._deps.logCallback(`creation of ${selectedContract.name} errored: ` + error)
- createInstanceCallback(selectedContract, data)
- })
- }
- })
- }
-
- if (selectedContract.contract.object.evm.deployedBytecode && selectedContract.contract.object.evm.deployedBytecode.object.length / 2 > 24576) {
- modalDialog('Contract code size over limit', yo`Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails.
- More info:
eip-170
-
`,
- {
- label: 'Force Send',
- fn: () => {
- forceSend()
- }}, {
- label: 'Cancel',
- fn: () => {
- self._deps.logCallback(`creation of ${selectedContract.name} canceled by user.`)
- }
- })
- } else {
- forceSend()
- }
- }
-
- // ACCESS DEPLOYED INSTANCE
- function loadFromAddress () {
- var noInstancesText = self._view.noInstancesText
- if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
- var address = atAddressButtonInput.value
- if (!ethJSUtil.isValidAddress(address)) {
- return modalDialogCustom.alert('Invalid address.')
- }
- if (/[a-f]/.test(address) && /[A-F]/.test(address) && !ethJSUtil.isValidChecksumAddress(address)) {
- return modalDialogCustom.alert('Invalid checksum address.')
- }
- if (/.(.abi)$/.exec(self._deps.config.get('currentFile'))) {
- modalDialogCustom.confirm(null, 'Do you really want to interact with ' + address + ' using the current ABI definition ?', () => {
- var abi
- try {
- abi = JSON.parse(self._deps.editor.currentContent())
- } catch (e) {
- return modalDialogCustom.alert('Failed to parse the current file as JSON ABI.')
- }
- instanceContainer.appendChild(self._deps.udappUI.renderInstanceFromABI(abi, address, address))
- })
- } else {
- var selectedContract = getSelectedContract()
- instanceContainer.appendChild(self._deps.udappUI.renderInstance(selectedContract.contract.object, address, selectContractNames.value))
- }
- }
-
- // GET NAMES OF ALL THE CONTRACTS
- function getContractNames (success, data, compiler, compilerFullName) {
- var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
- contractNames.innerHTML = ''
- if (success) {
- selectContractNames.removeAttribute('disabled')
- compiler.visitContracts((contract) => {
- contractNames.appendChild(yo``)
- })
- } else {
- selectContractNames.setAttribute('disabled', true)
- }
- setInputParamsPlaceHolder()
- }
-
- return el
-}
-/* ------------------------------------------------
- section SETTINGS: Environment, Account, Gas, Value
------------------------------------------------- */
-function settings (container, self) {
- // VARIABLES
- var net = yo``
- var networkcallid = 0
- const updateNetwork = (cb) => {
- networkcallid++
- (function (callid) {
- executionContext.detectNetwork((err, { id, name } = {}) => {
- if (networkcallid > callid) return
- networkcallid++
- if (err) {
- console.error(err)
- net.innerHTML = 'can\'t detect network '
- } else {
- net.innerHTML = ` ${name} (${id || '-'})`
- }
- if (cb) cb(err, {id, name})
- })
- })(networkcallid)
- }
- var environmentEl = yo`
-
-
- Environment
-
-
- ${net}
-
-
-
-
- `
- var accountEl = yo`
-
-
- Account
-
-
-
-
- ${copyToClipboard(() => document.querySelector('#runTabView #txorigin').value)}
-
-
-
- `
- var gasPriceEl = yo`
-
- `
- var valueEl = yo`
-
-
Value
-
-
-
- `
- // DOM ELEMENT
- var el = yo`
-
- ${environmentEl}
- ${accountEl}
- ${gasPriceEl}
- ${valueEl}
-
- `
- // HELPER FUNCTIONS AND EVENTS
- self._deps.udapp.event.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => {
- if (error) return
- if (!lookupOnly) el.querySelector('#value').value = '0'
- updateAccountBalances(container, self)
- })
-
- // DROPDOWN
- var selectExEnv = environmentEl.querySelector('#selectExEnvOptions')
-
- function setFinalContext () {
- // set the final context. Cause it is possible that this is not the one we've originaly selected
- selectExEnv.value = executionContext.getProvider()
- self.event.trigger('clearInstance', [])
- updateNetwork()
- fillAccountsList(el, self)
- }
-
- self.event.register('clearInstance', () => {
- var instanceContainer = self._view.instanceContainer
- var instanceContainerTitle = self._view.instanceContainerTitle
- instanceContainer.innerHTML = '' // clear the instances list
- instanceContainer.appendChild(instanceContainerTitle)
- instanceContainer.appendChild(self._view.noInstancesText)
- })
-
- executionContext.event.register('addProvider', (network) => {
- selectExEnv.appendChild(yo``)
- tootip(`${network.name} [${network.url}] added`)
- })
-
- executionContext.event.register('removeProvider', (name) => {
- var env = selectExEnv.querySelector(`option[value="${name}"]`)
- if (env) {
- selectExEnv.removeChild(env)
- tootip(`${name} removed`)
- }
- })
-
- selectExEnv.addEventListener('change', function (event) {
- let context = selectExEnv.options[selectExEnv.selectedIndex].value
- executionContext.executionContextChange(context, null, () => {
- modalDialogCustom.confirm(null, 'Are you sure you want to connect to an ethereum node?', () => {
- modalDialogCustom.prompt(null, 'Web3 Provider Endpoint', 'http://localhost:8545', (target) => {
- executionContext.setProviderFromEndpoint(target, context, (alertMsg) => {
- if (alertMsg) {
- modalDialogCustom.alert(alertMsg)
- }
- setFinalContext()
- })
- }, setFinalContext)
- }, setFinalContext)
- }, (alertMsg) => {
- modalDialogCustom.alert(alertMsg)
- }, setFinalContext)
- })
-
- selectExEnv.value = executionContext.getProvider()
- executionContext.event.register('contextChanged', (context, silent) => {
- setFinalContext()
- })
-
- setInterval(() => {
- updateNetwork()
- fillAccountsList(el, self)
- }, 5000)
-
- setInterval(() => {
- updateAccountBalances(container, self)
- }, 10000)
-
- function newAccount () {
- self._deps.udapp.newAccount('',
- (cb) => {
- modalCustom.promptPassphraseCreation((error, passphrase) => {
- if (error) {
- return modalCustom.alert(error)
- }
- cb(passphrase)
- }, () => {})
- },
- (error, address) => {
- if (!error) {
- addTooltip(`account ${address} created`)
- } else {
- addTooltip('Cannot create an account: ' + error)
- }
- }
- )
- }
- function signMessage (event) {
- self._deps.udapp.getAccounts((err, accounts) => {
- if (err) { addTooltip(`Cannot get account list: ${err}`) }
- var signMessageDialog = { 'title': 'Sign a message', 'text': 'Enter a message to sign', 'inputvalue': 'Message to sign' }
- var $txOrigin = container.querySelector('#txorigin')
- var account = $txOrigin.selectedOptions[0].value
- var isVM = executionContext.isVM()
- var isInjected = executionContext.getProvider() === 'injected'
- function alertSignedData (error, hash, signedData) {
- if (error && error.message !== '') {
- console.log(error)
- addTooltip(error.message)
- } else {
- modalDialogCustom.alert(yo`hash:${hash}
signature:${signedData}
`)
- }
- }
- if (isVM) {
- modalDialogCustom.promptMulti(signMessageDialog, (message) => {
- const personalMsg = ethJSUtil.hashPersonalMessage(Buffer.from(message))
- var privKey = self._deps.udapp.accounts[account].privateKey
- try {
- var rsv = ethJSUtil.ecsign(personalMsg, privKey)
- var signedData = ethJSUtil.toRpcSig(rsv.v, rsv.r, rsv.s)
- alertSignedData(null, '0x' + personalMsg.toString('hex'), signedData)
- } catch (e) {
- addTooltip(e.message)
- return
- }
- }, false)
- } else if (isInjected) {
- modalDialogCustom.promptMulti(signMessageDialog, (message) => {
- const hashedMsg = executionContext.web3().sha3(message)
- try {
- executionContext.web3().eth.sign(account, hashedMsg, (error, signedData) => {
- alertSignedData(error, hashedMsg, signedData)
- })
- } catch (e) {
- addTooltip(e.message)
- console.log(e)
- return
- }
- })
- } else {
- modalDialogCustom.promptPassphrase('Passphrase to sign a message', 'Enter your passphrase for this account to sign the message', '', (passphrase) => {
- modalDialogCustom.promptMulti(signMessageDialog, (message) => {
- const hashedMsg = executionContext.web3().sha3(message)
- try {
- var personal = new Personal(executionContext.web3().currentProvider)
- personal.sign(hashedMsg, account, passphrase, (error, signedData) => {
- alertSignedData(error, hashedMsg, signedData)
- })
- } catch (e) {
- addTooltip(e.message)
- console.log(e)
- return
- }
- })
- }, false)
- }
- })
- }
-
- return el
-}
module.exports = runTab
diff --git a/src/app/tabs/runTab/contractDropdown.js b/src/app/tabs/runTab/contractDropdown.js
new file mode 100644
index 0000000000..e3c23cad13
--- /dev/null
+++ b/src/app/tabs/runTab/contractDropdown.js
@@ -0,0 +1,391 @@
+var yo = require('yo-yo')
+var ethJSUtil = require('ethereumjs-util')
+var css = require('../styles/run-tab-styles')
+var executionContext = require('../../../execution-context')
+var modalDialogCustom = require('../../ui/modal-dialog-custom')
+var modalCustom = require('../../ui/modal-dialog-custom')
+var CompilerAbstract = require('../../compiler/compiler-abstract')
+var remixLib = require('remix-lib')
+var txExecution = remixLib.execution.txExecution
+var txFormat = remixLib.execution.txFormat
+var txHelper = remixLib.execution.txHelper
+var typeConversion = remixLib.execution.typeConversion
+var confirmDialog = require('../../execution/confirmDialog')
+var modalDialog = require('../../ui/modaldialog')
+var MultiParamManager = require('../../../multiParamManager')
+
+function contractDropdown (events, self) {
+ var instanceContainer = self._view.instanceContainer
+ var instanceContainerTitle = self._view.instanceContainerTitle
+ instanceContainer.appendChild(instanceContainerTitle)
+ instanceContainer.appendChild(self._view.noInstancesText)
+ var compFails = yo``
+ var info = yo``
+
+ var newlyCompiled = (success, data, source, compiler, compilerFullName) => {
+ getContractNames(success, data, compiler, compilerFullName)
+ if (success) {
+ compFails.style.display = 'none'
+ document.querySelector(`.${css.contractNames}`).classList.remove(css.contractNamesError)
+ } else {
+ compFails.style.display = 'block'
+ document.querySelector(`.${css.contractNames}`).classList.add(css.contractNamesError)
+ }
+ }
+
+ self._deps.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
+ // TODO check whether the tab is configured
+ let compiler = new CompilerAbstract(languageVersion, data)
+ self._deps.compilersArtefacts[languageVersion] = compiler
+ self._deps.compilersArtefacts['__last'] = compiler
+ newlyCompiled(true, data, source, compiler, languageVersion)
+ })
+
+ self._deps.compiler.event.register('compilationFinished', (success, data, source) => {
+ var name = 'solidity'
+ let compiler = new CompilerAbstract(name, data)
+ self._deps.compilersArtefacts[name] = compiler
+ self._deps.compilersArtefacts['__last'] = compiler
+ newlyCompiled(success, data, source, self._deps.compiler, name)
+ })
+
+ var deployAction = (value) => {
+ self._view.createPanel.style.display = value
+ self._view.orLabel.style.display = value
+ }
+
+ self._deps.fileManager.event.register('currentFileChanged', (currentFile) => {
+ document.querySelector(`.${css.contractNames}`).classList.remove(css.contractNamesError)
+ var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
+ contractNames.innerHTML = ''
+ if (/.(.abi)$/.exec(currentFile)) {
+ deployAction('none')
+ compFails.style.display = 'none'
+ contractNames.appendChild(yo``)
+ selectContractNames.setAttribute('disabled', true)
+ } else if (/.(.sol)$/.exec(currentFile)) {
+ deployAction('block')
+ }
+ })
+
+ var atAddressButtonInput = yo``
+ var selectContractNames = yo``
+
+ function getSelectedContract () {
+ var contract = selectContractNames.children[selectContractNames.selectedIndex]
+ var contractName = contract.innerHTML
+ var compiler = self._deps.compilersArtefacts[contract.getAttribute('compiler')]
+ if (!compiler) return null
+
+ if (contractName) {
+ return {
+ name: contractName,
+ contract: compiler.getContract(contractName),
+ compiler
+ }
+ }
+ return null
+ }
+
+ self._view.createPanel = yo``
+ self._view.orLabel = yo`or
`
+ var el = yo`
+
+
+ ${selectContractNames} ${compFails} ${info}
+
+
+ ${self._view.createPanel}
+ ${self._view.orLabel}
+
+
+
+ `
+
+ function setInputParamsPlaceHolder () {
+ self._view.createPanel.innerHTML = ''
+ if (selectContractNames.selectedIndex >= 0 && selectContractNames.children.length > 0) {
+ var selectedContract = getSelectedContract()
+ var ctrabi = txHelper.getConstructorInterface(selectedContract.contract.object.abi)
+ var ctrEVMbc = selectedContract.contract.object.evm.bytecode.object
+ var createConstructorInstance = new MultiParamManager(0, ctrabi, (valArray, inputsValues) => {
+ createInstance(inputsValues, selectedContract.compiler)
+ }, txHelper.inputParametersDeclarationToString(ctrabi.inputs), 'Deploy', ctrEVMbc)
+ self._view.createPanel.appendChild(createConstructorInstance.render())
+ return
+ } else {
+ self._view.createPanel.innerHTML = 'No compiled contracts'
+ }
+ }
+
+ selectContractNames.addEventListener('change', setInputParamsPlaceHolder)
+
+ function createInstanceCallback (selectedContract, data) {
+ self._deps.logCallback(`creation of ${selectedContract.name} pending...`)
+ if (data) {
+ data.contractName = selectedContract.name
+ data.linkReferences = selectedContract.contract.object.evm.bytecode.linkReferences
+ data.contractABI = selectedContract.contract.object.abi
+ }
+ 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, continueTxExecution, cancelCb) => {
+ if (error) {
+ var msg = typeof error !== 'string' ? error.message : error
+ modalDialog('Gas estimation failed', yo`Gas estimation errored with the following message (see below).
+ The transaction execution will likely fail. Do you want to force sending?
+ ${msg}
+
`,
+ {
+ label: 'Send Transaction',
+ fn: () => {
+ continueTxExecution()
+ }}, {
+ label: 'Cancel Transaction',
+ fn: () => {
+ cancelCb()
+ }
+ })
+ } else {
+ continueTxExecution()
+ }
+ },
+ function (okCb, cancelCb) {
+ modalCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
+ },
+ (error, txResult) => {
+ if (!error) {
+ var isVM = executionContext.isVM()
+ if (isVM) {
+ var vmError = txExecution.checkVMError(txResult)
+ if (vmError.error) {
+ self._deps.logCallback(vmError.message)
+ return
+ }
+ }
+ if (txResult.result.status && txResult.result.status === '0x0') {
+ self._deps.logCallback(`creation of ${selectedContract.name} errored: transaction execution failed`)
+ return
+ }
+ var noInstancesText = self._view.noInstancesText
+ if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
+ var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress
+ instanceContainer.appendChild(self._deps.udappUI.renderInstance(selectedContract.contract.object, address, selectContractNames.value))
+ } else {
+ self._deps.logCallback(`creation of ${selectedContract.name} errored: ${error}`)
+ }
+ }
+ )
+ }
+
+ // DEPLOY INSTANCE
+ function createInstance (args, compiler) {
+ var selectedContract = getSelectedContract()
+
+ if (selectedContract.contract.object.evm.bytecode.object.length === 0) {
+ modalDialogCustom.alert('This contract may be abstract, not implement an abstract parent\'s methods completely or not invoke an inherited contract\'s constructor correctly.')
+ return
+ }
+
+ var forceSend = () => {
+ var constructor = txHelper.getConstructorInterface(selectedContract.contract.object.abi)
+ self._deps.filePanel.compilerMetadata().deployMetadataOf(selectedContract.name, (error, contractMetadata) => {
+ if (error) return self._deps.logCallback(`creation of ${selectedContract.name} errored: ` + error)
+ if (!contractMetadata || (contractMetadata && contractMetadata.autoDeployLib)) {
+ txFormat.buildData(selectedContract.name, selectedContract.contract.object, compiler.getContracts(), true, constructor, args, (error, data) => {
+ if (error) return self._deps.logCallback(`creation of ${selectedContract.name} errored: ` + error)
+ createInstanceCallback(selectedContract, data)
+ }, (msg) => {
+ self._deps.logCallback(msg)
+ }, (data, runTxCallback) => {
+ // called for libraries deployment
+ 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.')
+ }
+ })
+ },
+ function (okCb, cancelCb) {
+ modalCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
+ },
+ runTxCallback)
+ })
+ } 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')}`)
+ txFormat.encodeConstructorCallAndLinkLibraries(selectedContract.contract.object, args, constructor, contractMetadata.linkReferences, selectedContract.contract.object.evm.bytecode.linkReferences, (error, data) => {
+ if (error) return self._deps.logCallback(`creation of ${selectedContract.name} errored: ` + error)
+ createInstanceCallback(selectedContract, data)
+ })
+ }
+ })
+ }
+
+ if (selectedContract.contract.object.evm.deployedBytecode && selectedContract.contract.object.evm.deployedBytecode.object.length / 2 > 24576) {
+ modalDialog('Contract code size over limit', yo`Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails.
+ More info:
eip-170
+
`,
+ {
+ label: 'Force Send',
+ fn: () => {
+ forceSend()
+ }}, {
+ label: 'Cancel',
+ fn: () => {
+ self._deps.logCallback(`creation of ${selectedContract.name} canceled by user.`)
+ }
+ })
+ } else {
+ forceSend()
+ }
+ }
+
+ // ACCESS DEPLOYED INSTANCE
+ function loadFromAddress () {
+ var noInstancesText = self._view.noInstancesText
+ if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
+ var address = atAddressButtonInput.value
+ if (!ethJSUtil.isValidAddress(address)) {
+ return modalDialogCustom.alert('Invalid address.')
+ }
+ if (/[a-f]/.test(address) && /[A-F]/.test(address) && !ethJSUtil.isValidChecksumAddress(address)) {
+ return modalDialogCustom.alert('Invalid checksum address.')
+ }
+ if (/.(.abi)$/.exec(self._deps.config.get('currentFile'))) {
+ modalDialogCustom.confirm(null, 'Do you really want to interact with ' + address + ' using the current ABI definition ?', () => {
+ var abi
+ try {
+ abi = JSON.parse(self._deps.editor.currentContent())
+ } catch (e) {
+ return modalDialogCustom.alert('Failed to parse the current file as JSON ABI.')
+ }
+ instanceContainer.appendChild(self._deps.udappUI.renderInstanceFromABI(abi, address, address))
+ })
+ } else {
+ var selectedContract = getSelectedContract()
+ instanceContainer.appendChild(self._deps.udappUI.renderInstance(selectedContract.contract.object, address, selectContractNames.value))
+ }
+ }
+
+ // GET NAMES OF ALL THE CONTRACTS
+ function getContractNames (success, data, compiler, compilerFullName) {
+ var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
+ contractNames.innerHTML = ''
+ if (success) {
+ selectContractNames.removeAttribute('disabled')
+ compiler.visitContracts((contract) => {
+ contractNames.appendChild(yo``)
+ })
+ } else {
+ selectContractNames.setAttribute('disabled', true)
+ }
+ setInputParamsPlaceHolder()
+ }
+
+ return el
+}
+
+module.exports = contractDropdown
diff --git a/src/app/tabs/runTab/settings.js b/src/app/tabs/runTab/settings.js
new file mode 100644
index 0000000000..6c7bb20029
--- /dev/null
+++ b/src/app/tabs/runTab/settings.js
@@ -0,0 +1,299 @@
+var $ = require('jquery')
+var yo = require('yo-yo')
+var ethJSUtil = require('ethereumjs-util')
+var Personal = require('web3-eth-personal')
+var css = require('../styles/run-tab-styles')
+var executionContext = require('../../../execution-context')
+var copyToClipboard = require('../../ui/copy-to-clipboard')
+var modalDialogCustom = require('../../ui/modal-dialog-custom')
+var addTooltip = require('../../ui/tooltip')
+var modalCustom = require('../../ui/modal-dialog-custom')
+var tootip = require('../../ui/tooltip')
+var helper = require('../../../lib/helper.js')
+
+function settings (container, self) {
+ // VARIABLES
+ var net = yo``
+ var networkcallid = 0
+ const updateNetwork = (cb) => {
+ networkcallid++
+ (function (callid) {
+ executionContext.detectNetwork((err, { id, name } = {}) => {
+ if (networkcallid > callid) return
+ networkcallid++
+ if (err) {
+ console.error(err)
+ net.innerHTML = 'can\'t detect network '
+ } else {
+ net.innerHTML = ` ${name} (${id || '-'})`
+ }
+ if (cb) cb(err, {id, name})
+ })
+ })(networkcallid)
+ }
+ var environmentEl = yo`
+
+
+ Environment
+
+
+ ${net}
+
+
+
+
+ `
+ var accountEl = yo`
+
+
+ Account
+
+
+
+
+ ${copyToClipboard(() => document.querySelector('#runTabView #txorigin').value)}
+
+
+
+ `
+ var gasPriceEl = yo`
+
+ `
+ var valueEl = yo`
+
+
Value
+
+
+
+ `
+ // DOM ELEMENT
+ var el = yo`
+
+ ${environmentEl}
+ ${accountEl}
+ ${gasPriceEl}
+ ${valueEl}
+
+ `
+ // HELPER FUNCTIONS AND EVENTS
+ self._deps.udapp.event.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => {
+ if (error) return
+ if (!lookupOnly) el.querySelector('#value').value = '0'
+ updateAccountBalances(container, self)
+ })
+
+ // DROPDOWN
+ var selectExEnv = environmentEl.querySelector('#selectExEnvOptions')
+
+ function setFinalContext () {
+ // set the final context. Cause it is possible that this is not the one we've originaly selected
+ selectExEnv.value = executionContext.getProvider()
+ self.event.trigger('clearInstance', [])
+ updateNetwork()
+ fillAccountsList(el, self)
+ }
+
+ self.event.register('clearInstance', () => {
+ var instanceContainer = self._view.instanceContainer
+ var instanceContainerTitle = self._view.instanceContainerTitle
+ instanceContainer.innerHTML = '' // clear the instances list
+ instanceContainer.appendChild(instanceContainerTitle)
+ instanceContainer.appendChild(self._view.noInstancesText)
+ })
+
+ executionContext.event.register('addProvider', (network) => {
+ selectExEnv.appendChild(yo``)
+ tootip(`${network.name} [${network.url}] added`)
+ })
+
+ executionContext.event.register('removeProvider', (name) => {
+ var env = selectExEnv.querySelector(`option[value="${name}"]`)
+ if (env) {
+ selectExEnv.removeChild(env)
+ tootip(`${name} removed`)
+ }
+ })
+
+ selectExEnv.addEventListener('change', function (event) {
+ let context = selectExEnv.options[selectExEnv.selectedIndex].value
+ executionContext.executionContextChange(context, null, () => {
+ modalDialogCustom.confirm(null, 'Are you sure you want to connect to an ethereum node?', () => {
+ modalDialogCustom.prompt(null, 'Web3 Provider Endpoint', 'http://localhost:8545', (target) => {
+ executionContext.setProviderFromEndpoint(target, context, (alertMsg) => {
+ if (alertMsg) {
+ modalDialogCustom.alert(alertMsg)
+ }
+ setFinalContext()
+ })
+ }, setFinalContext)
+ }, setFinalContext)
+ }, (alertMsg) => {
+ modalDialogCustom.alert(alertMsg)
+ }, setFinalContext)
+ })
+
+ selectExEnv.value = executionContext.getProvider()
+ executionContext.event.register('contextChanged', (context, silent) => {
+ setFinalContext()
+ })
+
+ setInterval(() => {
+ updateNetwork()
+ fillAccountsList(el, self)
+ }, 5000)
+
+ setInterval(() => {
+ updateAccountBalances(container, self)
+ }, 10000)
+
+ function newAccount () {
+ self._deps.udapp.newAccount('',
+ (cb) => {
+ modalCustom.promptPassphraseCreation((error, passphrase) => {
+ if (error) {
+ return modalCustom.alert(error)
+ }
+ cb(passphrase)
+ }, () => {})
+ },
+ (error, address) => {
+ if (!error) {
+ addTooltip(`account ${address} created`)
+ } else {
+ addTooltip('Cannot create an account: ' + error)
+ }
+ }
+ )
+ }
+ function signMessage (event) {
+ self._deps.udapp.getAccounts((err, accounts) => {
+ if (err) { addTooltip(`Cannot get account list: ${err}`) }
+ var signMessageDialog = { 'title': 'Sign a message', 'text': 'Enter a message to sign', 'inputvalue': 'Message to sign' }
+ var $txOrigin = container.querySelector('#txorigin')
+ var account = $txOrigin.selectedOptions[0].value
+ var isVM = executionContext.isVM()
+ var isInjected = executionContext.getProvider() === 'injected'
+ function alertSignedData (error, hash, signedData) {
+ if (error && error.message !== '') {
+ console.log(error)
+ addTooltip(error.message)
+ } else {
+ modalDialogCustom.alert(yo`hash:${hash}
signature:${signedData}
`)
+ }
+ }
+ if (isVM) {
+ modalDialogCustom.promptMulti(signMessageDialog, (message) => {
+ const personalMsg = ethJSUtil.hashPersonalMessage(Buffer.from(message))
+ var privKey = self._deps.udapp.accounts[account].privateKey
+ try {
+ var rsv = ethJSUtil.ecsign(personalMsg, privKey)
+ var signedData = ethJSUtil.toRpcSig(rsv.v, rsv.r, rsv.s)
+ alertSignedData(null, '0x' + personalMsg.toString('hex'), signedData)
+ } catch (e) {
+ addTooltip(e.message)
+ return
+ }
+ }, false)
+ } else if (isInjected) {
+ modalDialogCustom.promptMulti(signMessageDialog, (message) => {
+ const hashedMsg = executionContext.web3().sha3(message)
+ try {
+ executionContext.web3().eth.sign(account, hashedMsg, (error, signedData) => {
+ alertSignedData(error, hashedMsg, signedData)
+ })
+ } catch (e) {
+ addTooltip(e.message)
+ console.log(e)
+ return
+ }
+ })
+ } else {
+ modalDialogCustom.promptPassphrase('Passphrase to sign a message', 'Enter your passphrase for this account to sign the message', '', (passphrase) => {
+ modalDialogCustom.promptMulti(signMessageDialog, (message) => {
+ const hashedMsg = executionContext.web3().sha3(message)
+ try {
+ var personal = new Personal(executionContext.web3().currentProvider)
+ personal.sign(hashedMsg, account, passphrase, (error, signedData) => {
+ alertSignedData(error, hashedMsg, signedData)
+ })
+ } catch (e) {
+ addTooltip(e.message)
+ console.log(e)
+ return
+ }
+ })
+ }, false)
+ }
+ })
+ }
+
+ return el
+}
+
+var accountListCallId = 0
+var loadedAccounts = {}
+function fillAccountsList (container, self) {
+ accountListCallId++
+ (function (callid) {
+ var txOrigin = container.querySelector('#txorigin')
+ self._deps.udapp.getAccounts((err, accounts) => {
+ if (accountListCallId > callid) return
+ accountListCallId++
+ if (err) { addTooltip(`Cannot get account list: ${err}`) }
+ for (var loadedaddress in loadedAccounts) {
+ if (accounts.indexOf(loadedaddress) === -1) {
+ txOrigin.removeChild(txOrigin.querySelector('option[value="' + loadedaddress + '"]'))
+ delete loadedAccounts[loadedaddress]
+ }
+ }
+ for (var i in accounts) {
+ var address = accounts[i]
+ if (!loadedAccounts[address]) {
+ txOrigin.appendChild(yo``)
+ loadedAccounts[address] = 1
+ }
+ }
+ txOrigin.setAttribute('value', accounts[0])
+ })
+ })(accountListCallId)
+}
+
+function updateAccountBalances (container, self) {
+ var accounts = $(container.querySelector('#txorigin')).children('option')
+ accounts.each(function (index, value) {
+ (function (acc) {
+ self._deps.udapp.getBalanceInEther(accounts[acc].value, function (err, res) {
+ if (!err) {
+ accounts[acc].innerText = helper.shortenAddress(accounts[acc].value, res)
+ }
+ })
+ })(index)
+ })
+}
+
+module.exports = settings