parent
3700e675e4
commit
54871aba44
@ -1 +1 @@ |
||||
export * from './lib/remix-ui-run-tab'; |
||||
export * from './lib/run-tab' |
||||
|
@ -0,0 +1,8 @@ |
||||
let plugin, dispatch: React.Dispatch<any> |
||||
|
||||
const initSettingsTab = (udapp) => async (reducerDispatch: React.Dispatch<any>) => { |
||||
plugin = udapp |
||||
dispatch = reducerDispatch |
||||
|
||||
|
||||
} |
@ -0,0 +1,149 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React, { useRef, useState } from 'react' |
||||
import { CopyToClipboard } from '@remix-ui/clipboard' |
||||
import { AccountProps } from '../types' |
||||
|
||||
export function AccountUI (props: AccountProps) { |
||||
const [selectedAccount, setSelectedAccount] = useState<string>('') |
||||
const plusBtn = useRef(null) |
||||
const plusTitle = useRef(null) |
||||
|
||||
// // TODO: unclear what's the goal of accountListCallId, feels like it can be simplified
|
||||
// async fillAccountsList () {
|
||||
// this.accountListCallId++
|
||||
// const callid = this.accountListCallId
|
||||
// const txOrigin = this.el.querySelector('#txorigin')
|
||||
// let accounts = []
|
||||
// try {
|
||||
// accounts = await this.blockchain.getAccounts()
|
||||
// } catch (e) {
|
||||
// addTooltip(`Cannot get account list: ${e}`)
|
||||
// }
|
||||
// if (!accounts) accounts = []
|
||||
// if (this.accountListCallId > callid) return
|
||||
// this.accountListCallId++
|
||||
// for (const loadedaddress in this.loadedAccounts) {
|
||||
// if (accounts.indexOf(loadedaddress) === -1) {
|
||||
// txOrigin.removeChild(txOrigin.querySelector('option[value="' + loadedaddress + '"]'))
|
||||
// delete this.loadedAccounts[loadedaddress]
|
||||
// }
|
||||
// }
|
||||
// for (const i in accounts) {
|
||||
// const address = accounts[i]
|
||||
// if (!this.loadedAccounts[address]) {
|
||||
// txOrigin.appendChild(yo`<option value="${address}" >${address}</option>`)
|
||||
// this.loadedAccounts[address] = 1
|
||||
// }
|
||||
// }
|
||||
// txOrigin.setAttribute('value', accounts[0])
|
||||
// }
|
||||
|
||||
const updatePlusButton = () => { |
||||
// enable/disable + button
|
||||
switch (props.selectExEnv) { |
||||
case 'injected': |
||||
plusBtn.current.classList.add('udapp_disableMouseEvents') |
||||
plusTitle.current.title = "Unfortunately it's not possible to create an account using injected web3. Please create the account directly from your provider (i.e metamask or other of the same type)." |
||||
|
||||
break |
||||
case 'vm': |
||||
plusBtn.current.classList.remove('udapp_disableMouseEvents') |
||||
plusTitle.current.title = 'Create a new account' |
||||
|
||||
break |
||||
|
||||
case 'web3': |
||||
this.onPersonalChange() |
||||
|
||||
break |
||||
default: { |
||||
plusBtn.current.classList.add('udapp_disableMouseEvents') |
||||
plusTitle.current.title = `Unfortunately it's not possible to create an account using an external wallet (${props.selectExEnv}).` |
||||
} |
||||
} |
||||
} |
||||
|
||||
const newAccount = () => { |
||||
// dispatch createNewBlockchainAccount
|
||||
// this.blockchain.newAccount(
|
||||
// '',
|
||||
// (cb) => {
|
||||
// modalDialogCustom.promptPassphraseCreation((error, passphrase) => {
|
||||
// if (error) {
|
||||
// return modalDialogCustom.alert(error)
|
||||
// }
|
||||
// cb(passphrase)
|
||||
// }, () => {})
|
||||
// },
|
||||
// (error, address) => {
|
||||
// if (error) {
|
||||
// return addTooltip('Cannot create an account: ' + error)
|
||||
// }
|
||||
// addTooltip(`account ${address} created`)
|
||||
// }
|
||||
// )
|
||||
} |
||||
|
||||
const signMessage = () => { |
||||
// dispatch signMessageWithBlockchainAccounts
|
||||
// this.blockchain.getAccounts((err, accounts) => {
|
||||
// if (err) {
|
||||
// return addTooltip(`Cannot get account list: ${err}`)
|
||||
// }
|
||||
|
||||
// var signMessageDialog = { title: 'Sign a message', text: 'Enter a message to sign', inputvalue: 'Message to sign' }
|
||||
// var $txOrigin = this.el.querySelector('#txorigin')
|
||||
// if (!$txOrigin.selectedOptions[0] && (this.blockchain.isInjectedWeb3() || this.blockchain.isWeb3Provider())) {
|
||||
// return addTooltip('Account list is empty, please make sure the current provider is properly connected to remix')
|
||||
// }
|
||||
|
||||
// var account = $txOrigin.selectedOptions[0].value
|
||||
|
||||
// var promptCb = (passphrase) => {
|
||||
// const modal = modalDialogCustom.promptMulti(signMessageDialog, (message) => {
|
||||
// this.blockchain.signMessage(message, account, passphrase, (err, msgHash, signedData) => {
|
||||
// if (err) {
|
||||
// return addTooltip(err)
|
||||
// }
|
||||
// modal.hide()
|
||||
// modalDialogCustom.alert(yo`
|
||||
// <div>
|
||||
// <b>hash:</b><br>
|
||||
// <span id="remixRunSignMsgHash" data-id="settingsRemixRunSignMsgHash">${msgHash}</span>
|
||||
// <br><b>signature:</b><br>
|
||||
// <span id="remixRunSignMsgSignature" data-id="settingsRemixRunSignMsgSignature">${signedData}</span>
|
||||
// </div>
|
||||
// `)
|
||||
// })
|
||||
// }, false)
|
||||
// }
|
||||
|
||||
// if (this.blockchain.isWeb3Provider()) {
|
||||
// return modalDialogCustom.promptPassphrase(
|
||||
// 'Passphrase to sign a message',
|
||||
// 'Enter your passphrase for this account to sign the message',
|
||||
// '',
|
||||
// promptCb,
|
||||
// false
|
||||
// )
|
||||
// }
|
||||
// promptCb()
|
||||
// })
|
||||
} |
||||
|
||||
return ( |
||||
<div className="udapp_crow"> |
||||
<label className="udapp_settingsLabel"> |
||||
Account |
||||
<span ref={plusTitle} id="remixRunPlusWraper" title="Create a new account" onLoad={updatePlusButton}> |
||||
<i ref={plusBtn} id="remixRunPlus" className="fas fa-plus-circle udapp_icon" aria-hidden="true" onClick={newAccount}></i> |
||||
</span> |
||||
</label> |
||||
<div className="udapp_account"> |
||||
<select id="txorigin" data-id="runTabSelectAccount" name="txorigin" className="form-control udapp_select custom-select pr-4" value={selectedAccount} onChange={(e) => { setSelectedAccount(e.target.value) }}></select> |
||||
<div style={{ marginLeft: -5 }}><CopyToClipboard content={selectedAccount} direction='top' /></div> |
||||
<i id="remixRunSignMsg" data-id="settingsRemixRunSignMsg" className="mx-1 fas fa-edit udapp_icon" aria-hidden="true" onClick={signMessage} title="Sign a message using this account key"></i> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
@ -0,0 +1,418 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React, { SyntheticEvent, useEffect, useRef, useState } from 'react' |
||||
import { ContractDropdownProps } from '../types' |
||||
import * as ethJSUtil from 'ethereumjs-util' |
||||
|
||||
export function ContractDropdownUI (props: ContractDropdownProps) { |
||||
const [networkName, setNetworkName] = useState<string>('') |
||||
const [abiLabel, setAbiLabel] = useState<{ |
||||
display: string, |
||||
content: string |
||||
}>({ |
||||
display: '', |
||||
content: '' |
||||
}) |
||||
const [ipfsCheckedState, setIpfsCheckedState] = useState<boolean>(false) |
||||
const [loadType] = useState<string>('other') |
||||
const atAddressButtonInput = useRef(null) |
||||
const contracts = useRef(null) |
||||
|
||||
useEffect(() => { |
||||
enableAtAddress(false) |
||||
const savedConfig = window.localStorage.getItem(`ipfs/${props.exEnvironment}/${networkName}`) |
||||
const isCheckedIPFS = savedConfig === 'true' ? true : false // eslint-disable-line
|
||||
|
||||
if (isCheckedIPFS) setIpfsCheckedState(true) |
||||
setAbiLabel({ |
||||
display: 'none', |
||||
content: 'ABI file selected' |
||||
}) |
||||
}, []) |
||||
|
||||
useEffect(() => { |
||||
if (props.exEnvironment === 'vm') setNetworkName('VM') |
||||
}, [props.exEnvironment]) |
||||
|
||||
const enableAtAddress = (enable) => { |
||||
const atAddress = atAddressButtonInput.current |
||||
|
||||
if (enable) { |
||||
if (!atAddress.value || !ethJSUtil.isValidAddress(atAddress.value)) { |
||||
enableAtAddress(false) |
||||
return |
||||
} |
||||
atAddress.removeAttribute('disabled') |
||||
atAddress.setAttribute('title', 'Interact with the given contract.') |
||||
} else { |
||||
atAddress.setAttribute('disabled', true) |
||||
if (atAddress.value === '') { |
||||
atAddress.setAttribute('title', '⚠ Compile *.sol file or select *.abi file & then enter the address of deployed contract.') |
||||
} else { |
||||
atAddress.setAttribute('title', '⚠ Compile *.sol file or select *.abi file.') |
||||
} |
||||
} |
||||
} |
||||
// constructor (blockchain, dropdownLogic, logCallback, runView) {
|
||||
// this.blockchain = blockchain
|
||||
// this.dropdownLogic = dropdownLogic
|
||||
// this.logCallback = logCallback
|
||||
// this.runView = runView
|
||||
// this.event = new EventManager()
|
||||
|
||||
// this.listenToEvents()
|
||||
// this.ipfsCheckedState = false
|
||||
// this.exEnvironment = blockchain.getProvider()
|
||||
// this.listenToContextChange()
|
||||
// this.loadType = 'other'
|
||||
// }
|
||||
|
||||
// listenToEvents () {
|
||||
// this.dropdownLogic.event.register('newlyCompiled', (success, data, source, compiler, compilerFullName, file) => {
|
||||
// if (!this.selectContractNames) return
|
||||
// this.selectContractNames.innerHTML = ''
|
||||
// if (success) {
|
||||
// this.dropdownLogic.getCompiledContracts(compiler, compilerFullName).forEach((contract) => {
|
||||
// this.selectContractNames.appendChild(yo`<option value="${contract.name}" compiler="${compilerFullName}">${contract.name} - ${contract.file}</option>`)
|
||||
// })
|
||||
// }
|
||||
// this.enableAtAddress(success)
|
||||
// this.enableContractNames(success)
|
||||
// this.setInputParamsPlaceHolder()
|
||||
|
||||
// if (success) {
|
||||
// this.compFails.style.display = 'none'
|
||||
// } else {
|
||||
// this.compFails.style.display = 'block'
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// listenToContextChange () {
|
||||
// this.blockchain.event.register('networkStatus', ({ error, network }) => {
|
||||
// if (error) {
|
||||
// console.log('can\'t detect network')
|
||||
// return
|
||||
// }
|
||||
// this.exEnvironment = this.blockchain.getProvider()
|
||||
// this.networkName = network.name
|
||||
|
||||
// const savedConfig = window.localStorage.getItem(`ipfs/${this.exEnvironment}/${this.networkName}`)
|
||||
|
||||
// // check if an already selected option exist else use default workflow
|
||||
// if (savedConfig !== null) {
|
||||
// this.setCheckedState(savedConfig)
|
||||
// } else {
|
||||
// this.setCheckedState(this.networkName === 'Main')
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// setCheckedState (value) {
|
||||
// value = value === 'true' ? true : value === 'false' ? false : value
|
||||
// this.ipfsCheckedState = value
|
||||
// if (this.ipfsCheckbox) this.ipfsCheckbox.checked = value
|
||||
// }
|
||||
|
||||
// enableContractNames (enable) {
|
||||
// if (enable) {
|
||||
// if (this.selectContractNames.value === '') return
|
||||
// this.selectContractNames.removeAttribute('disabled')
|
||||
// this.selectContractNames.setAttribute('title', 'Select contract for Deploy or At Address.')
|
||||
// } else {
|
||||
// this.selectContractNames.setAttribute('disabled', true)
|
||||
// if (this.loadType === 'sol') {
|
||||
// this.selectContractNames.setAttribute('title', '⚠ Select and compile *.sol file to deploy or access a contract.')
|
||||
// } else {
|
||||
// this.selectContractNames.setAttribute('title', '⚠ Selected *.abi file allows accessing contracts, select and compile *.sol file to deploy and access one.')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// changeCurrentFile (currentFile) {
|
||||
// if (!this.selectContractNames) return
|
||||
// if (/.(.abi)$/.exec(currentFile)) {
|
||||
// this.createPanel.style.display = 'none'
|
||||
// this.orLabel.style.display = 'none'
|
||||
// this.compFails.style.display = 'none'
|
||||
// this.loadType = 'abi'
|
||||
// this.contractNamesContainer.style.display = 'block'
|
||||
// this.abiLabel.style.display = 'block'
|
||||
// this.abiLabel.innerHTML = currentFile
|
||||
// this.selectContractNames.style.display = 'none'
|
||||
// this.enableContractNames(true)
|
||||
// this.enableAtAddress(true)
|
||||
// } else if (/.(.sol)$/.exec(currentFile) ||
|
||||
// /.(.vy)$/.exec(currentFile) || // vyper
|
||||
// /.(.lex)$/.exec(currentFile) || // lexon
|
||||
// /.(.contract)$/.exec(currentFile)) {
|
||||
// this.createPanel.style.display = 'block'
|
||||
// this.orLabel.style.display = 'block'
|
||||
// this.contractNamesContainer.style.display = 'block'
|
||||
// this.loadType = 'sol'
|
||||
// this.selectContractNames.style.display = 'block'
|
||||
// this.abiLabel.style.display = 'none'
|
||||
// if (this.selectContractNames.value === '') this.enableAtAddress(false)
|
||||
// } else {
|
||||
// this.loadType = 'other'
|
||||
// this.createPanel.style.display = 'block'
|
||||
// this.orLabel.style.display = 'block'
|
||||
// this.contractNamesContainer.style.display = 'block'
|
||||
// this.selectContractNames.style.display = 'block'
|
||||
// this.abiLabel.style.display = 'none'
|
||||
// if (this.selectContractNames.value === '') this.enableAtAddress(false)
|
||||
// }
|
||||
// }
|
||||
|
||||
// setInputParamsPlaceHolder () {
|
||||
// this.createPanel.innerHTML = ''
|
||||
// if (this.selectContractNames.selectedIndex < 0 || this.selectContractNames.children.length <= 0) {
|
||||
// this.createPanel.innerHTML = 'No compiled contracts'
|
||||
// return
|
||||
// }
|
||||
|
||||
// const selectedContract = this.getSelectedContract()
|
||||
// const clickCallback = async (valArray, inputsValues) => {
|
||||
// var selectedContract = this.getSelectedContract()
|
||||
// this.createInstance(selectedContract, inputsValues)
|
||||
// }
|
||||
// const createConstructorInstance = new MultiParamManager(
|
||||
// 0,
|
||||
// selectedContract.getConstructorInterface(),
|
||||
// clickCallback,
|
||||
// selectedContract.getConstructorInputs(),
|
||||
// 'Deploy',
|
||||
// selectedContract.bytecodeObject,
|
||||
// true
|
||||
// )
|
||||
// this.createPanel.appendChild(createConstructorInstance.render())
|
||||
// this.createPanel.appendChild(this.deployCheckBox)
|
||||
// }
|
||||
|
||||
// getSelectedContract () {
|
||||
// var contract = this.selectContractNames.children[this.selectContractNames.selectedIndex]
|
||||
// var contractName = contract.getAttribute('value')
|
||||
// var compilerAtributeName = contract.getAttribute('compiler')
|
||||
|
||||
// return this.dropdownLogic.getSelectedContract(contractName, compilerAtributeName)
|
||||
// }
|
||||
|
||||
// async createInstance (selectedContract, args) {
|
||||
// if (selectedContract.bytecodeObject.length === 0) {
|
||||
// return modalDialogCustom.alert('This contract may be abstract, not implement an abstract parent\'s methods completely or not invoke an inherited contract\'s constructor correctly.')
|
||||
// }
|
||||
|
||||
// var continueCb = (error, continueTxExecution, cancelCb) => {
|
||||
// if (error) {
|
||||
// var msg = typeof error !== 'string' ? error.message : error
|
||||
// modalDialog('Gas estimation failed', yo`<div>Gas estimation errored with the following message (see below).
|
||||
// The transaction execution will likely fail. Do you want to force sending? <br>
|
||||
// ${msg}
|
||||
// </div>`,
|
||||
// {
|
||||
// label: 'Send Transaction',
|
||||
// fn: () => {
|
||||
// continueTxExecution()
|
||||
// }
|
||||
// }, {
|
||||
// label: 'Cancel Transaction',
|
||||
// fn: () => {
|
||||
// cancelCb()
|
||||
// }
|
||||
// })
|
||||
// } else {
|
||||
// continueTxExecution()
|
||||
// }
|
||||
// }
|
||||
|
||||
// const self = this
|
||||
|
||||
// var promptCb = (okCb, cancelCb) => {
|
||||
// modalDialogCustom.promptPassphrase('Passphrase requested', 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
|
||||
// }
|
||||
|
||||
// var statusCb = (msg) => {
|
||||
// return this.logCallback(msg)
|
||||
// }
|
||||
|
||||
// var finalCb = (error, contractObject, address) => {
|
||||
// self.event.trigger('clearInstance')
|
||||
|
||||
// if (error) {
|
||||
// return this.logCallback(error)
|
||||
// }
|
||||
// self.event.trigger('newContractInstanceAdded', [contractObject, address, contractObject.name])
|
||||
|
||||
// const data = self.runView.compilersArtefacts.getCompilerAbstract(contractObject.contract.file)
|
||||
// self.runView.compilersArtefacts.addResolvedContract(helper.addressToString(address), data)
|
||||
// if (self.ipfsCheckedState) {
|
||||
// _paq.push(['trackEvent', 'udapp', 'DeployAndPublish', this.networkName])
|
||||
// publishToStorage('ipfs', self.runView.fileProvider, self.runView.fileManager, selectedContract)
|
||||
// } else {
|
||||
// _paq.push(['trackEvent', 'udapp', 'DeployOnly', this.networkName])
|
||||
// }
|
||||
// }
|
||||
|
||||
// let contractMetadata
|
||||
// try {
|
||||
// contractMetadata = await this.runView.call('compilerMetadata', 'deployMetadataOf', selectedContract.name, selectedContract.contract.file)
|
||||
// } catch (error) {
|
||||
// return statusCb(`creation of ${selectedContract.name} errored: ${error.message ? error.message : error}`)
|
||||
// }
|
||||
|
||||
// const compilerContracts = this.dropdownLogic.getCompilerContracts()
|
||||
// const confirmationCb = this.getConfirmationCb(modalDialog, confirmDialog)
|
||||
|
||||
// if (selectedContract.isOverSizeLimit()) {
|
||||
// return modalDialog('Contract code size over limit', yo`<div>Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails. <br>
|
||||
// More info: <a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-170.md" target="_blank">eip-170</a>
|
||||
// </div>`,
|
||||
// {
|
||||
// label: 'Force Send',
|
||||
// fn: () => {
|
||||
// this.deployContract(selectedContract, args, contractMetadata, compilerContracts, { continueCb, promptCb, statusCb, finalCb }, confirmationCb)
|
||||
// }
|
||||
// }, {
|
||||
// label: 'Cancel',
|
||||
// fn: () => {
|
||||
// this.logCallback(`creation of ${selectedContract.name} canceled by user.`)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// this.deployContract(selectedContract, args, contractMetadata, compilerContracts, { continueCb, promptCb, statusCb, finalCb }, confirmationCb)
|
||||
// }
|
||||
|
||||
// deployContract (selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) {
|
||||
// _paq.push(['trackEvent', 'udapp', 'DeployContractTo', this.networkName])
|
||||
// const { statusCb } = callbacks
|
||||
// if (!contractMetadata || (contractMetadata && contractMetadata.autoDeployLib)) {
|
||||
// return this.blockchain.deployContractAndLibraries(selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb)
|
||||
// }
|
||||
// if (Object.keys(selectedContract.bytecodeLinkReferences).length) statusCb(`linking ${JSON.stringify(selectedContract.bytecodeLinkReferences, null, '\t')} using ${JSON.stringify(contractMetadata.linkReferences, null, '\t')}`)
|
||||
// this.blockchain.deployContractWithLibrary(selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb)
|
||||
// }
|
||||
|
||||
// getConfirmationCb (modalDialog, confirmDialog) {
|
||||
// // this code is the same as in recorder.js. TODO need to be refactored out
|
||||
// const confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => {
|
||||
// if (network.name !== 'Main') {
|
||||
// return continueTxExecution(null)
|
||||
// }
|
||||
// const amount = this.blockchain.fromWei(tx.value, true, 'ether')
|
||||
// const content = confirmDialog(tx, network, amount, gasEstimation, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice.bind(this.blockchain))
|
||||
|
||||
// modalDialog('Confirm transaction', content,
|
||||
// {
|
||||
// label: 'Confirm',
|
||||
// fn: () => {
|
||||
// this.blockchain.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 transaction fee is not correct')
|
||||
// } else {
|
||||
// continueTxExecution(content.txFee)
|
||||
// }
|
||||
// }
|
||||
// }, {
|
||||
// label: 'Cancel',
|
||||
// fn: () => {
|
||||
// return cancelCb('Transaction canceled by user.')
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
|
||||
// return confirmationCb
|
||||
// }
|
||||
|
||||
const atAddressChanged = (event: SyntheticEvent) => { |
||||
const atAddress = atAddressButtonInput.current |
||||
const selectContractNames = contracts.current |
||||
|
||||
if (!atAddress.value) { |
||||
enableAtAddress(false) |
||||
} else { |
||||
if ((selectContractNames && !selectContractNames.getAttribute('disabled') && loadType === 'sol') || |
||||
loadType === 'abi') { |
||||
enableAtAddress(true) |
||||
} else { |
||||
enableAtAddress(false) |
||||
} |
||||
} |
||||
} |
||||
|
||||
const loadFromAddress = () => { |
||||
// trigger dispatchLoadAddress
|
||||
// this.event.trigger('clearInstance')
|
||||
|
||||
// let address = this.atAddressButtonInput.value
|
||||
// if (!ethJSUtil.isValidChecksumAddress(address)) {
|
||||
// addTooltip(yo`
|
||||
// <span>
|
||||
// It seems you are not using a checksumed address.
|
||||
// <br>A checksummed address is an address that contains uppercase letters, as specified in <a href="https://eips.ethereum.org/EIPS/eip-55" target="_blank">EIP-55</a>.
|
||||
// <br>Checksummed addresses are meant to help prevent users from sending transactions to the wrong address.
|
||||
// </span>`)
|
||||
// address = ethJSUtil.toChecksumAddress(address)
|
||||
// }
|
||||
// this.dropdownLogic.loadContractFromAddress(address,
|
||||
// (cb) => {
|
||||
// modalDialogCustom.confirm('At Address', `Do you really want to interact with ${address} using the current ABI definition?`, cb)
|
||||
// },
|
||||
// (error, loadType, abi) => {
|
||||
// if (error) {
|
||||
// return modalDialogCustom.alert(error)
|
||||
// }
|
||||
// if (loadType === 'abi') {
|
||||
// return this.event.trigger('newContractABIAdded', [abi, address])
|
||||
// }
|
||||
// var selectedContract = this.getSelectedContract()
|
||||
// this.event.trigger('newContractInstanceAdded', [selectedContract.object, address, this.selectContractNames.value])
|
||||
// }
|
||||
// )
|
||||
} |
||||
|
||||
const handleCheckedIPFS = () => { |
||||
setIpfsCheckedState(!ipfsCheckedState) |
||||
window.localStorage.setItem(`ipfs/${props.exEnvironment}/${networkName}`, ipfsCheckedState.toString()) |
||||
} |
||||
|
||||
return ( |
||||
<div className="udapp_container" data-id="contractDropdownContainer"> |
||||
<label className="udapp_settingsLabel">Contract</label> |
||||
<div className="udapp_subcontainer"> |
||||
<select ref={contracts} className="udapp_contractNames custom-select" disabled title="Please compile *.sol file to deploy or access a contract"></select> |
||||
<i title="No contract compiled yet or compilation failed. Please check the compile tab for more information." className="m-2 ml-3 fas fa-times-circle udapp_errorIcon" ></i> |
||||
<span className="py-1" style={{ display: abiLabel.display }}>{ abiLabel.content }</span> |
||||
</div> |
||||
<div> |
||||
<div className="udapp_deployDropdown"> |
||||
<div className="d-flex py-1 align-items-center custom-control custom-checkbox"> |
||||
<input |
||||
id="deployAndRunPublishToIPFS" |
||||
data-id="contractDropdownIpfsCheckbox" |
||||
className="form-check-input custom-control-input" |
||||
type="checkbox" |
||||
onChange={handleCheckedIPFS} |
||||
checked={ipfsCheckedState} |
||||
/> |
||||
<label |
||||
htmlFor="deployAndRunPublishToIPFS" |
||||
data-id="contractDropdownIpfsCheckboxLabel" |
||||
className="m-0 form-check-label custom-control-label udapp_checkboxAlign" |
||||
title="Publishing the source code and metadata to IPFS facilitates source code verification using Sourcify and will greatly foster contract adoption (auditing, debugging, calling it, etc...)" |
||||
> |
||||
Publish to IPFS |
||||
</label> |
||||
</div> |
||||
</div> |
||||
<div className="udapp_orLabel mt-2">or</div> |
||||
<div className="udapp_button udapp_atAddressSect"> |
||||
<button className="udapp_atAddress btn btn-sm btn-info" id="runAndDeployAtAdressButton" onClick={loadFromAddress}>At Address</button> |
||||
<input ref={atAddressButtonInput} className="udapp_input udapp_ataddressinput ataddressinput form-control" placeholder="Load contract from Address" title="address of contract" onInput={atAddressChanged} /> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
// this.selectContractNames.addEventListener('change', this.setInputParamsPlaceHolder.bind(this))
|
||||
// this.setInputParamsPlaceHolder()
|
||||
) |
||||
} |
@ -0,0 +1,76 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React, { useState } from 'react' |
||||
import { EnvironmentProps } from '../types' |
||||
|
||||
export function EnvironmentUI (props: EnvironmentProps) { |
||||
const [exEnv, setExEnv] = useState<string>('') |
||||
|
||||
// setDropdown (selectExEnv) {
|
||||
// this.selectExEnv = selectExEnv
|
||||
|
||||
// const addProvider = (network) => {
|
||||
// selectExEnv.appendChild(yo`<option
|
||||
// title="provider name: ${network.name}"
|
||||
// value="${network.name}"
|
||||
// name="executionContext"
|
||||
// >
|
||||
// ${network.name}
|
||||
// </option>`)
|
||||
// addTooltip(yo`<span><b>${network.name}</b> provider added</span>`)
|
||||
// }
|
||||
|
||||
// const removeProvider = (name) => {
|
||||
// var env = selectExEnv.querySelector(`option[value="${name}"]`)
|
||||
// if (env) {
|
||||
// selectExEnv.removeChild(env)
|
||||
// addTooltip(yo`<span><b>${name}</b> provider removed</span>`)
|
||||
// }
|
||||
// }
|
||||
// this.blockchain.event.register('addProvider', provider => addProvider(provider))
|
||||
// this.blockchain.event.register('removeProvider', name => removeProvider(name))
|
||||
|
||||
// selectExEnv.addEventListener('change', (event) => {
|
||||
// const provider = selectExEnv.options[selectExEnv.selectedIndex]
|
||||
// const fork = provider.getAttribute('fork') // can be undefined if connected to an external source (web3 provider / injected)
|
||||
// let context = provider.value
|
||||
// context = context.startsWith('vm') ? 'vm' : context // context has to be 'vm', 'web3' or 'injected'
|
||||
// this.setExecutionContext({ context, fork })
|
||||
// })
|
||||
|
||||
// selectExEnv.value = this._getProviderDropdownValue()
|
||||
// }
|
||||
|
||||
const handleChangeExEnv = (env: string) => { |
||||
setExEnv(env) |
||||
props.updateExEnv(env) |
||||
} |
||||
return ( |
||||
<div className="udapp_crow"> |
||||
<label id="selectExEnv" className="udapp_settingsLabel"> |
||||
Environment |
||||
</label> |
||||
<div className="udapp_environment"> |
||||
<select id="selectExEnvOptions" data-id="settingsSelectEnvOptions" className="form-control udapp_select custom-select" value={exEnv} onChange={(e) => { handleChangeExEnv(e.target.value) }}> |
||||
<option id="vm-mode-london" data-id="settingsVMLondonMode" |
||||
title="Execution environment does not connect to any node, everything is local and in memory only." |
||||
value="vm-london"> JavaScript VM (London) {/* fork="london" */} |
||||
</option> |
||||
<option id="vm-mode-berlin" data-id="settingsVMBerlinMode" |
||||
title="Execution environment does not connect to any node, everything is local and in memory only." |
||||
value="vm-berlin"> JavaScript VM (Berlin) {/* fork="berlin" */} |
||||
</option> |
||||
<option id="injected-mode" data-id="settingsInjectedMode" |
||||
title="Execution environment has been provided by Metamask or similar provider." |
||||
value="injected"> Injected Web3 |
||||
</option> |
||||
<option id="web3-mode" data-id="settingsWeb3Mode" |
||||
title="Execution environment connects to node at localhost (or via IPC if available), transactions will be sent to the network and can cause loss of money or worse! |
||||
If this page is served via https and you access your node via http, it might not work. In this case, try cloning the repository and serving it via http." |
||||
value="web3"> Web3 Provider |
||||
</option> |
||||
</select> |
||||
<a href="https://remix-ide.readthedocs.io/en/latest/run.html#run-setup" target="_blank"><i className="udapp_infoDeployAction ml-2 fas fa-info" title="check out docs to setup Environment"></i></a> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
@ -0,0 +1,12 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React from 'react' |
||||
import { GasPriceProps } from '../types' |
||||
|
||||
export function GasPriceUI (props: GasPriceProps) { |
||||
return ( |
||||
<div className="udapp_crow"> |
||||
<label className="udapp_settingsLabel">Gas limit</label> |
||||
<input type="number" className="form-control udapp_gasNval udapp_col2" id="gasLimit" defaultValue="3000000" /> |
||||
</div> |
||||
) |
||||
} |
@ -0,0 +1,15 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React from 'react' |
||||
import { NetworkProps } from '../types' |
||||
|
||||
export function NetworkUI (props: NetworkProps) { |
||||
return ( |
||||
<div className="udapp_crow"> |
||||
<div className="udapp_settingsLabel"> |
||||
</div> |
||||
<div className="udapp_environment" data-id="settingsNetworkEnv"> |
||||
<span className="udapp_network badge badge-secondary"></span> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
@ -0,0 +1,156 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React from 'react' |
||||
import { SettingsProps } from '../types' |
||||
import { EnvironmentUI } from './environment' |
||||
import { NetworkUI } from './network' |
||||
import { AccountUI } from './account' |
||||
import { GasPriceUI } from './gasPrice' |
||||
import { ValueUI } from './value' |
||||
|
||||
export function SettingsUI (props: SettingsProps) { |
||||
// constructor () {
|
||||
// this.blockchain = blockchain
|
||||
// this.event = new EventManager()
|
||||
// this._components = {}
|
||||
|
||||
// this.blockchain.event.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => {
|
||||
// if (!lookupOnly) this.el.querySelector('#value').value = 0
|
||||
// if (error) return
|
||||
// this.updateAccountBalances()
|
||||
// })
|
||||
// this._components = {
|
||||
// registry: globalRegistry,
|
||||
// networkModule: networkModule
|
||||
// }
|
||||
// this._components.registry = globalRegistry
|
||||
// this._deps = {
|
||||
// config: this._components.registry.get('config').api
|
||||
// }
|
||||
|
||||
// this._deps.config.events.on('settings/personal-mode_changed', this.onPersonalChange.bind(this))
|
||||
|
||||
// setInterval(() => {
|
||||
// this.updateAccountBalances()
|
||||
// }, 1000)
|
||||
|
||||
// this.accountListCallId = 0
|
||||
// this.loadedAccounts = {}
|
||||
// }
|
||||
|
||||
// updateAccountBalances () {
|
||||
// if (!this.el) return
|
||||
// var accounts = $(this.el.querySelector('#txorigin')).children('option')
|
||||
// accounts.each((index, account) => {
|
||||
// this.blockchain.getBalanceInEther(account.value, (err, balance) => {
|
||||
// if (err) return
|
||||
// const updated = helper.shortenAddress(account.value, balance)
|
||||
// if (updated !== account.innerText) { // check if the balance has been updated and update UI accordingly.
|
||||
// account.innerText = updated
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
|
||||
// setExecutionContext (context) {
|
||||
// this.blockchain.changeExecutionContext(context, () => {
|
||||
// modalDialogCustom.prompt('External node request', this.web3ProviderDialogBody(), 'http://127.0.0.1:8545', (target) => {
|
||||
// this.blockchain.setProviderFromEndpoint(target, context, (alertMsg) => {
|
||||
// if (alertMsg) addTooltip(alertMsg)
|
||||
// this.setFinalContext()
|
||||
// })
|
||||
// }, this.setFinalContext.bind(this))
|
||||
// }, (alertMsg) => {
|
||||
// addTooltip(alertMsg)
|
||||
// }, this.setFinalContext.bind(this))
|
||||
// }
|
||||
|
||||
// web3ProviderDialogBody () {
|
||||
// const thePath = '<path/to/local/folder/for/test/chain>'
|
||||
|
||||
// return yo`
|
||||
// <div class="">
|
||||
// Note: To use Geth & https://remix.ethereum.org, configure it to allow requests from Remix:(see <a href="https://geth.ethereum.org/docs/rpc/server" target="_blank">Geth Docs on rpc server</a>)
|
||||
// <div class="border p-1">geth --http --http.corsdomain https://remix.ethereum.org</div>
|
||||
// <br>
|
||||
// To run Remix & a local Geth test node, use this command: (see <a href="https://geth.ethereum.org/getting-started/dev-mode" target="_blank">Geth Docs on Dev mode</a>)
|
||||
// <div class="border p-1">geth --http --http.corsdomain="${window.origin}" --http.api web3,eth,debug,personal,net --vmdebug --datadir ${thePath} --dev console</div>
|
||||
// <br>
|
||||
// <br>
|
||||
// <b>WARNING:</b> It is not safe to use the --http.corsdomain flag with a wildcard: <b>--http.corsdomain *</b>
|
||||
// <br>
|
||||
// <br>For more info: <a href="https://remix-ide.readthedocs.io/en/latest/run.html#more-about-web3-provider" target="_blank">Remix Docs on Web3 Provider</a>
|
||||
// <br>
|
||||
// <br>
|
||||
// Web3 Provider Endpoint
|
||||
// </div>
|
||||
// `
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * generate a value used by the env dropdown list.
|
||||
// * @return {String} - can return 'vm-berlin, 'vm-london', 'injected' or 'web3'
|
||||
// */
|
||||
// _getProviderDropdownValue () {
|
||||
// const provider = this.blockchain.getProvider()
|
||||
// const fork = this.blockchain.getCurrentFork()
|
||||
// return provider === 'vm' ? provider + '-' + fork : provider
|
||||
// }
|
||||
|
||||
// setFinalContext () {
|
||||
// // set the final context. Cause it is possible that this is not the one we've originaly selected
|
||||
// this.selectExEnv.value = this._getProviderDropdownValue()
|
||||
// this.event.trigger('clearInstance', [])
|
||||
// this.updatePlusButton()
|
||||
// }
|
||||
|
||||
// onPersonalChange () {
|
||||
// const plusBtn = document.getElementById('remixRunPlus')
|
||||
// const plusTitle = document.getElementById('remixRunPlusWraper')
|
||||
// if (!this._deps.config.get('settings/personal-mode')) {
|
||||
// plusBtn.classList.add(css.disableMouseEvents)
|
||||
// plusTitle.title = 'Creating an account is possible only in Personal mode. Please go to Settings to enable it.'
|
||||
// } else {
|
||||
// plusBtn.classList.remove(css.disableMouseEvents)
|
||||
// plusTitle.title = 'Create a new account'
|
||||
// }
|
||||
// }
|
||||
|
||||
// getSelectedAccount () {
|
||||
// return this.el.querySelector('#txorigin').selectedOptions[0].value
|
||||
// }
|
||||
|
||||
// getEnvironment () {
|
||||
// return this.blockchain.getProvider()
|
||||
// }
|
||||
|
||||
return ( |
||||
// this.blockchain.event.register('contextChanged', (context, silent) => {
|
||||
// this.setFinalContext()
|
||||
// })
|
||||
|
||||
// this.blockchain.event.register('networkStatus', ({ error, network }) => {
|
||||
// if (error) {
|
||||
// this.netUI.innerHTML = 'can\'t detect network '
|
||||
// return
|
||||
// }
|
||||
// const networkProvider = this._components.networkModule.getNetworkProvider.bind(this._components.networkModule)
|
||||
// this.netUI.innerHTML = (networkProvider() !== 'vm') ? `${network.name} (${network.id || '-'}) network` : ''
|
||||
// })
|
||||
|
||||
// setInterval(() => {
|
||||
// this.fillAccountsList()
|
||||
// }, 1000)
|
||||
|
||||
// this.el = el
|
||||
|
||||
// this.fillAccountsList()
|
||||
// return el
|
||||
<div className="udapp_settings"> |
||||
<EnvironmentUI updateExEnv={props.updateExEnv} /> |
||||
<NetworkUI /> |
||||
<AccountUI selectExEnv={props.selectExEnv} /> |
||||
<GasPriceUI /> |
||||
<ValueUI /> |
||||
</div> |
||||
) |
||||
} |
@ -0,0 +1,69 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React, { useRef } from 'react' |
||||
import { BN } from 'ethereumjs-util' |
||||
import { isNumeric } from '@remix-ui/helper' |
||||
import { ValueProps } from '../types' |
||||
|
||||
export function ValueUI (props: ValueProps) { |
||||
const inputValue = useRef(null) |
||||
|
||||
const validateInputKey = (e) => { |
||||
// preventing not numeric keys
|
||||
// preventing 000 case
|
||||
if (!isNumeric(e.key) || |
||||
(e.key === '0' && !parseInt(inputValue.current.value) && inputValue.current.value.length > 0)) { |
||||
e.preventDefault() |
||||
e.stopImmediatePropagation() |
||||
} |
||||
} |
||||
|
||||
const validateValue = () => { |
||||
if (!inputValue.current.value) { |
||||
// assign 0 if given value is
|
||||
// - empty
|
||||
inputValue.current.value = 0 |
||||
return |
||||
} |
||||
|
||||
let v |
||||
try { |
||||
v = new BN(inputValue.current.value, 10) |
||||
inputValue.current.value = v.toString(10) |
||||
} catch (e) { |
||||
// assign 0 if given value is
|
||||
// - not valid (for ex 4345-54)
|
||||
// - contains only '0's (for ex 0000) copy past or edit
|
||||
inputValue.current.value = 0 |
||||
} |
||||
|
||||
// if giveen value is negative(possible with copy-pasting) set to 0
|
||||
if (v.lt(0)) inputValue.current.value = 0 |
||||
} |
||||
|
||||
return ( |
||||
<div className="udapp_crow"> |
||||
<label className="udapp_settingsLabel" data-id="remixDRValueLabel">Value</label> |
||||
<div className="udapp_gasValueContainer"> |
||||
<input |
||||
type="number" |
||||
min="0" |
||||
pattern="^[0-9]" |
||||
step="1" |
||||
className="form-control udapp_gasNval udapp_col2" |
||||
id="value" |
||||
data-id="dandrValue" |
||||
value="0" |
||||
title="Enter the value and choose the unit" |
||||
onKeyPress={validateInputKey} |
||||
onChange={validateValue} |
||||
/> |
||||
<select name="unit" className="form-control p-1 udapp_gasNvalUnit udapp_col2_2 custom-select" id="unit"> |
||||
<option data-unit="wei">Wei</option> |
||||
<option data-unit="gwei">Gwei</option> |
||||
<option data-unit="finney">Finney</option> |
||||
<option data-unit="ether">Ether</option> |
||||
</select> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
@ -0,0 +1,219 @@ |
||||
.udapp_runTabView { |
||||
display: flex; |
||||
flex-direction: column; |
||||
} |
||||
.udapp_runTabView::-webkit-scrollbar { |
||||
display: none; |
||||
} |
||||
.udapp_settings { |
||||
padding: 0 24px 16px; |
||||
} |
||||
.udapp_crow { |
||||
display: block; |
||||
margin-top: 8px; |
||||
} |
||||
.udapp_col1 { |
||||
width: 30%; |
||||
float: left; |
||||
align-self: center; |
||||
} |
||||
.udapp_settingsLabel { |
||||
font-size: 11px; |
||||
margin-bottom: 4px; |
||||
text-transform: uppercase; |
||||
} |
||||
.udapp_environment { |
||||
display: flex; |
||||
align-items: center; |
||||
position: relative; |
||||
width: 100%; |
||||
} |
||||
.udapp_environment a { |
||||
margin-left: 7px; |
||||
} |
||||
.udapp_account { |
||||
display: flex; |
||||
align-items: center; |
||||
} |
||||
.udapp_account i { |
||||
margin-left: 12px; |
||||
} |
||||
.udapp_col2 { |
||||
border-radius: 3px; |
||||
} |
||||
.udapp_col2_1 { |
||||
width: 164px; |
||||
min-width: 164px; |
||||
} |
||||
.udapp_col2_2 { |
||||
} |
||||
.udapp_select { |
||||
font-weight: normal; |
||||
width: 100%; |
||||
overflow: hidden; |
||||
} |
||||
.udapp_instanceContainer { |
||||
display: flex; |
||||
flex-direction: column; |
||||
margin-bottom: 2%; |
||||
border: none; |
||||
text-align: center; |
||||
padding: 0 14px 16px; |
||||
} |
||||
.udapp_pendingTxsContainer { |
||||
display: flex; |
||||
flex-direction: column; |
||||
margin-top: 2%; |
||||
border: none; |
||||
text-align: center; |
||||
} |
||||
.udapp_container { |
||||
padding: 0 24px 16px; |
||||
} |
||||
.udapp_recorderDescription { |
||||
margin: 0 15px 15px 0; |
||||
} |
||||
.udapp_contractNames { |
||||
width: 100%; |
||||
border: 1px solid |
||||
} |
||||
.udapp_subcontainer { |
||||
display: flex; |
||||
flex-direction: row; |
||||
align-items: center; |
||||
margin-bottom: 8px; |
||||
} |
||||
.udapp_subcontainer i { |
||||
width: 16px; |
||||
display: flex; |
||||
justify-content: center; |
||||
margin-left: 1px; |
||||
} |
||||
.udapp_button button{ |
||||
flex: none; |
||||
} |
||||
.udapp_button { |
||||
display: flex; |
||||
align-items: center; |
||||
margin-top: 13px; |
||||
} |
||||
.udapp_transaction { |
||||
} |
||||
.udapp_atAddress { |
||||
margin: 0; |
||||
min-width: 100px; |
||||
width: 100px; |
||||
height: 100%; |
||||
word-break: inherit; |
||||
border-top-right-radius: 0; |
||||
border-bottom-right-radius: 0; |
||||
border-right: 0; |
||||
} |
||||
.udapp_atAddressSect { |
||||
margin-top: 8px; |
||||
height: 32px; |
||||
} |
||||
.udapp_atAddressSect input { |
||||
height: 32px; |
||||
border-top-left-radius: 0 !important; |
||||
border-bottom-left-radius: 0 !important; |
||||
} |
||||
.udapp_ataddressinput { |
||||
padding: .25rem; |
||||
} |
||||
.udapp_create { |
||||
} |
||||
.udapp_input { |
||||
font-size: 10px !important; |
||||
} |
||||
.udapp_noInstancesText { |
||||
font-style: italic; |
||||
text-align: left; |
||||
padding-left: 15px; |
||||
} |
||||
.udapp_pendingTxsText { |
||||
font-style: italic; |
||||
display: flex; |
||||
justify-content: space-evenly; |
||||
align-items: center; |
||||
flex-wrap: wrap; |
||||
} |
||||
.udapp_item { |
||||
margin-right: 1em; |
||||
display: flex; |
||||
align-items: center; |
||||
} |
||||
.udapp_pendingContainer { |
||||
display: flex; |
||||
align-items: baseline; |
||||
} |
||||
.udapp_pending { |
||||
height: 25px; |
||||
text-align: center; |
||||
padding-left: 10px; |
||||
border-radius: 3px; |
||||
margin-left: 5px; |
||||
} |
||||
.udapp_disableMouseEvents { |
||||
pointer-events: none; |
||||
} |
||||
.udapp_icon { |
||||
cursor: pointer; |
||||
font-size: 12px; |
||||
cursor: pointer; |
||||
margin-left: 5px; |
||||
} |
||||
.udapp_icon:hover { |
||||
font-size: 12px; |
||||
color: var(--warning); |
||||
} |
||||
.udapp_errorIcon { |
||||
color: var(--warning); |
||||
margin-left: 15px; |
||||
} |
||||
.udapp_failDesc { |
||||
color: var(--warning); |
||||
padding-left: 10px; |
||||
display: inline; |
||||
} |
||||
.udapp_network { |
||||
margin-left: 8px; |
||||
pointer-events: none; |
||||
} |
||||
.udapp_networkItem { |
||||
margin-right: 5px; |
||||
} |
||||
.udapp_transactionActions { |
||||
display: flex; |
||||
justify-content: space-evenly; |
||||
width: 145px; |
||||
} |
||||
.udapp_orLabel { |
||||
text-align: center; |
||||
text-transform: uppercase; |
||||
} |
||||
.udapp_infoDeployAction { |
||||
margin-left: 1px; |
||||
font-size: 13px; |
||||
color: var(--info); |
||||
} |
||||
.udapp_gasValueContainer { |
||||
flex-direction: row; |
||||
display: flex; |
||||
} |
||||
.udapp_gasNval { |
||||
width: 55%; |
||||
font-size: 0.8rem; |
||||
} |
||||
.udapp_gasNvalUnit { |
||||
width: 41%; |
||||
margin-left: 10px; |
||||
font-size: 0.8rem; |
||||
} |
||||
.udapp_deployDropdown { |
||||
text-align: center; |
||||
text-transform: uppercase; |
||||
} |
||||
.udapp_checkboxAlign { |
||||
padding-top: 2px; |
||||
} |
@ -1,14 +0,0 @@ |
||||
import './remix-ui-run-tab.module.css'; |
||||
|
||||
/* eslint-disable-next-line */ |
||||
export interface RemixUiRunTabProps {} |
||||
|
||||
export function RemixUiRunTab(props: RemixUiRunTabProps) { |
||||
return ( |
||||
<div> |
||||
<h1>Welcome to remix-ui-run-tab!</h1> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default RemixUiRunTab; |
@ -0,0 +1,25 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React, { useState } from 'react' |
||||
import { ContractDropdownUI } from './components/contractDropdownUI' |
||||
import { SettingsUI } from './components/settingsUI' |
||||
import './css/run-tab.css' |
||||
import { RunTabProps } from './types' |
||||
|
||||
export function RunTabUI (props: RunTabProps) { |
||||
const [selectExEnv, setSelectExEnv] = useState<string>('') |
||||
|
||||
const updateExEnv = (env: string) => { |
||||
setSelectExEnv(env) |
||||
} |
||||
|
||||
return ( |
||||
<div className="udapp_runTabView run-tab" id="runTabView" data-id="runTabView"> |
||||
<div className="list-group list-group-flush"> |
||||
<SettingsUI selectExEnv={selectExEnv} updateExEnv={updateExEnv} /> |
||||
<ContractDropdownUI exEnvironment={selectExEnv} /> |
||||
{/* ${this.recorderCard.render()} |
||||
${this.instanceContainer} */} |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
@ -0,0 +1,32 @@ |
||||
export interface RunTabProps { |
||||
plugin: any |
||||
} |
||||
|
||||
export interface SettingsProps { |
||||
selectExEnv: string, |
||||
updateExEnv: (env: string) => void |
||||
} |
||||
|
||||
export interface EnvironmentProps { |
||||
updateExEnv: (env: string) => void |
||||
} |
||||
|
||||
export interface NetworkProps { |
||||
|
||||
} |
||||
|
||||
export interface AccountProps { |
||||
selectExEnv: string |
||||
} |
||||
|
||||
export interface GasPriceProps { |
||||
|
||||
} |
||||
|
||||
export interface ValueProps { |
||||
|
||||
} |
||||
|
||||
export interface ContractDropdownProps { |
||||
exEnvironment: string |
||||
} |
Loading…
Reference in new issue