Update mainnet modal from reducer

yann300-patch-36
David Disu 3 years ago committed by yann300
parent a1e9e748de
commit 95b0e4f248
  1. 8
      apps/remix-ide/src/app/udapp/run-tab.js
  2. 2
      libs/remix-ui/publish-to-storage/src/lib/types/index.ts
  3. 94
      libs/remix-ui/run-tab/src/lib/actions/index.ts
  4. 49
      libs/remix-ui/run-tab/src/lib/actions/payload.ts
  5. 63
      libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx
  6. 146
      libs/remix-ui/run-tab/src/lib/components/mainnet.tsx
  7. 10
      libs/remix-ui/run-tab/src/lib/css/run-tab.css
  8. 79
      libs/remix-ui/run-tab/src/lib/reducers/runTab.ts
  9. 49
      libs/remix-ui/run-tab/src/lib/run-tab.tsx
  10. 42
      libs/remix-ui/run-tab/src/lib/types/index.ts

@ -234,4 +234,12 @@ export class RunTab extends ViewPlugin {
onReady (api) {
this.REACT_API = api
}
writeFile (fileName, content) {
return this.call('fileManager', 'writeFile', fileName, content)
}
readFile (fileName) {
return this.call('fileManager', 'readFile', fileName)
}
}

@ -1,6 +1,6 @@
export interface RemixUiPublishToStorageProps {
api: any,
storage: string,
storage: 'swarm' | 'ipfs',
contract: any,
resetStorage: () => void
}

@ -3,10 +3,11 @@ import React from 'react'
import * as ethJSUtil from 'ethereumjs-util'
import Web3 from 'web3'
import { addressToString, shortenAddress } from '@remix-ui/helper'
import { addProvider, displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, fetchContractListSuccess, hidePopUp, removeProvider, setCurrentFile, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setLoadType, setMatchPassphrase, setNetworkName, setPassphrase, setSelectedAccount, setSendUnit, setSendValue } from './payload'
import { addProvider, displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, fetchContractListSuccess, hidePopUp, removeProvider, setBaseFeePerGas, setConfirmSettings, setCurrentFile, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setGasPrice, setGasPriceStatus, setIpfsCheckedState, setLoadType, setMatchPassphrase, setMaxFee, setMaxPriorityFee, setNetworkName, setPassphrase, setSelectedAccount, setSendUnit, setSendValue, setTxFeeContent } from './payload'
import { RunTab } from '../types/run-tab'
import { CompilerAbstract } from '@remix-project/remix-solidity'
import * as remixLib from '@remix-project/remix-lib'
import { ContractData } from '../types'
declare global {
interface Window {
_paq: any
@ -386,8 +387,33 @@ const terminalLogger = (view: JSX.Element) => {
plugin.call('terminal', 'logHtml', view)
}
const getConfirmationCb = () => {
// 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 = plugin.blockchain.fromWei(tx.value, true, 'ether')
const content = confirmDialog(tx, network, amount, gasEstimation, plugin.blockchain.determineGasFees(tx), plugin.blockchain.determineGasPrice.bind(plugin.blockchain))
dispatch(displayNotification('Confirm transaction', content, 'Confirm', 'Cancel', () => {
plugin.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)
}
}, () => {
return cancelCb('Transaction canceled by user.')
}))
}
return confirmationCb
}
// eslint-disable-next-line no-undef
export const createInstance = (gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, logBuilder: (msg: string) => JSX.Element) => {
export const createInstance = async (selectedContract: ContractData, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, logBuilder: (msg: string) => JSX.Element, publishToStorage: (storage: 'ipfs' | 'swarm', contract: ContractData) => void) => {
const continueCb = (error, continueTxExecution, cancelCb) => {
if (error) {
const msg = typeof error !== 'string' ? error.message : error
@ -424,23 +450,23 @@ export const createInstance = (gasEstimationPrompt: (msg: string) => JSX.Element
const data = plugin.compilersArtefacts.getCompilerAbstract(contractObject.contract.file)
plugin.compilersArtefacts.addResolvedContract(addressToString(address), data)
if (self.ipfsCheckedState) {
_paq.push(['trackEvent', 'udapp', 'DeployAndPublish', this.networkName])
publishToStorage('ipfs', self.runView.fileProvider, self.runView.fileManager, selectedContract)
if (plugin.REACT_API.ipfsChecked) {
_paq.push(['trackEvent', 'udapp', 'DeployAndPublish', plugin.REACT_API.networkName])
publishToStorage('ipfs', selectedContract)
} else {
_paq.push(['trackEvent', 'udapp', 'DeployOnly', plugin.REACT_API.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}`)
// }
let contractMetadata
try {
contractMetadata = await plugin.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)
const compilerContracts = getCompilerContracts()
const confirmationCb = getConfirmationCb(mainnetPrompt)
// 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>
@ -460,3 +486,45 @@ export const createInstance = (gasEstimationPrompt: (msg: string) => JSX.Element
// }
// this.deployContract(selectedContract, args, contractMetadata, compilerContracts, { continueCb, promptCb, statusCb, finalCb }, confirmationCb)
}
const deployContract = (selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) => {
_paq.push(['trackEvent', 'udapp', 'DeployContractTo', this.networkName + '_' + this.networkId])
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)
}
export const setCheckIpfs = (value: boolean) => {
dispatch(setIpfsCheckedState(value))
}
export const updateGasPriceStatus = (status: boolean) => {
dispatch(setGasPriceStatus(status))
}
export const updateConfirmSettings = (confirmation: boolean) => {
dispatch(setConfirmSettings(confirmation))
}
export const updateMaxFee = (fee: string) => {
dispatch(setMaxFee(fee))
}
export const updateMaxPriorityFee = (fee: string) => {
dispatch(setMaxPriorityFee(fee))
}
export const updateBaseFeePerGas = (baseFee: string) => {
dispatch(setBaseFeePerGas(baseFee))
}
export const updateGasPrice = (price: string) => {
dispatch(setGasPrice(price))
}
export const updateTxFeeContent = (content: string) => {
dispatch(setTxFeeContent(content))
}

@ -169,3 +169,52 @@ export const setIpfsCheckedState = (state: boolean) => {
payload: state
}
}
export const setGasPriceStatus = (status: boolean) => {
return {
type: 'SET_GAS_PRICE_STATUS',
payload: status
}
}
export const setConfirmSettings = (confirmation: boolean) => {
return {
type: 'SET_CONFIRM_SETTINGS',
payload: confirmation
}
}
export const setMaxFee = (fee: string) => {
return {
type: 'SET_MAX_FEE',
payload: fee
}
}
export const setMaxPriorityFee = (fee: string) => {
return {
type: 'SET_MAX_PRIORITY_FEE',
payload: fee
}
}
export const setBaseFeePerGas = (baseFee: string) => {
return {
type: 'SET_BASE_FEE_PER_GAS',
payload: baseFee
}
}
export const setGasPrice = (price: string) => {
return {
type: 'SET_GAS_PRICE',
payload: price
}
}
export const setTxFeeContent = (content: string) => {
return {
type: 'SET_TX_FEE_CONTENT',
payload: content
}
}

@ -1,6 +1,6 @@
// eslint-disable-next-line no-use-before-define
import React, { useEffect, useState } from 'react'
import { ContractDropdownProps } from '../types'
import { ContractData, ContractDropdownProps } from '../types'
import * as ethJSUtil from 'ethereumjs-util'
import { ContractGUI } from './contractGUI'
import { PassphrasePrompt } from './passphrase'
@ -14,7 +14,6 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
display: '',
content: ''
})
const [ipfsCheckedState, setIpfsCheckedState] = useState<boolean>(false)
const [atAddressOptions, setAtAddressOptions] = useState<{title: string, disabled: boolean}>({
title: 'address of contract',
disabled: true
@ -26,19 +25,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
})
const [selectedContract, setSelectedContract] = useState<string>('')
const [compFails, setCompFails] = useState<'none' | 'block'>('none')
const [loadedContractData, setLoadedContractData] = useState<{
name: string,
contract: string,
compiler: any,
abi: any,
bytecodeObject: any,
bytecodeLinkReferences: any,
object: any,
deployedBytecode: any,
getConstructorInterface: () => any,
getConstructorInputs: () => any,
isOverSizeLimit: () => boolean,
metadata: any}>(null)
const [loadedContractData, setLoadedContractData] = useState<ContractData>(null)
const { contractList, loadType, currentFile } = props.contracts
useEffect(() => {
@ -46,7 +33,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
const savedConfig = window.localStorage.getItem(`ipfs/${props.exEnvironment}/${networkName}`)
const isCheckedIPFS = savedConfig === 'true' ? true : false // eslint-disable-line
if (isCheckedIPFS) setIpfsCheckedState(true)
if (isCheckedIPFS) props.setIpfsCheckedState(true)
setAbiLabel({
display: 'none',
content: 'ABI file selected'
@ -134,7 +121,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
if (selectedContract.bytecodeObject.length === 0) {
return props.modal('Alert', 'This contract may be abstract, not implement an abstract parent\'s methods completely or not invoke an inherited contract\'s constructor correctly.', 'OK', () => {})
}
props.createInstance(gasEstimationPrompt, passphrasePrompt, logBuilder)
props.createInstance(loadedContractData, gasEstimationPrompt, passphrasePrompt, logBuilder, props.publishToStorage)
}
// listenToContextChange () {
@ -285,22 +272,6 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
// return confirmationCb
// }
const gasEstimationPrompt = (msg: string) => {
return (
<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>
)
}
const logBuilder = (msg: string) => {
return <pre>{msg}</pre>
}
const passphrasePrompt = (message: string) => {
return <PassphrasePrompt message={message} setPassphrase={props.setPassphrase} defaultValue={props.passphrase} />
}
const atAddressChanged = (event) => {
const value = event.target.value
@ -349,8 +320,8 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
}
const handleCheckedIPFS = () => {
setIpfsCheckedState(!ipfsCheckedState)
window.localStorage.setItem(`ipfs/${props.exEnvironment}/${networkName}`, ipfsCheckedState.toString())
props.setIpfsCheckedState(!props.ipfsCheckedState)
window.localStorage.setItem(`ipfs/${props.exEnvironment}/${networkName}`, props.ipfsCheckedState.toString())
}
const handleContractChange = (e) => {
@ -359,6 +330,26 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
setSelectedContract(value)
}
const gasEstimationPrompt = (msg: string) => {
return (
<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>
)
}
const logBuilder = (msg: string) => {
return <pre>{msg}</pre>
}
const passphrasePrompt = (message: string) => {
return <PassphrasePrompt message={message} setPassphrase={props.setPassphrase} defaultValue={props.passphrase} />
}
const mainnetPrompt = () => {
}
return (
<div className="udapp_container" data-id="contractDropdownContainer">
<label className="udapp_settingsLabel">Contract</label>
@ -383,7 +374,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
className="form-check-input custom-control-input"
type="checkbox"
onChange={handleCheckedIPFS}
checked={ipfsCheckedState}
checked={props.ipfsCheckedState}
/>
<label
htmlFor="deployAndRunPublishToIPFS"

@ -0,0 +1,146 @@
// eslint-disable-next-line no-use-before-define
import React, { useEffect } from 'react'
import { CopyToClipboard } from '@remix-ui/clipboard'
import Web3 from 'web3'
interface MainnetProps {
network: {
name: string,
lastBlock: {
baseFeePerGas: string
}
},
tx: {
from: string,
to: string,
data: string,
gas: string
},
amount: string,
gasEstimation: string,
setNewGasPrice: (maxFee: string, cb: (txFeeText: string, priceStatus: boolean) => void) => void,
updateGasPriceStatus: (status: boolean) => void,
updateConfirmSettings: (confirmation: boolean) => void,
updateMaxFee: (fee: string) => void,
updateBaseFeePerGas: (fee: string) => void,
init: (cb: (txFeeText: string, gasPriceValue: string, gasPriceStatus: boolean) => void) => void,
setTxFeeContent: (content: string) => void,
updateGasPrice: (price: string) => void,
txFeeContent: string
}
export function PassphrasePrompt (props: MainnetProps) {
useEffect(() => {
props.init((txFeeText, gasPriceValue, gasPriceStatus) => {
if (txFeeText) props.setTxFeeContent(txFeeText)
if (gasPriceValue) onGasPriceChange(gasPriceValue)
if (props.network && props.network.lastBlock && props.network.lastBlock.baseFeePerGas) onMaxFeeChange(Web3.utils.fromWei(Web3.utils.toBN(parseInt(props.network.lastBlock.baseFeePerGas, 16)), 'Gwei'))
if (gasPriceStatus !== undefined) props.updateGasPriceStatus(gasPriceStatus)
})
}, [])
const onMaxFeeChange = (value: string) => {
const maxFee = value
// @ts-ignore
if (parseInt(props.network.lastBlock.baseFeePerGas, 16) > Web3.utils.toWei(maxFee, 'Gwei')) {
props.setTxFeeContent('Transaction is invalid. Max fee should not be less than Base fee')
props.updateGasPriceStatus(false)
props.updateConfirmSettings(true)
return
} else {
props.updateGasPriceStatus(true)
props.updateConfirmSettings(false)
}
props.setNewGasPrice(maxFee, (txFeeText, priceStatus) => {
props.setTxFeeContent(txFeeText)
if (priceStatus) {
props.updateConfirmSettings(false)
} else {
props.updateConfirmSettings(true)
}
props.updateGasPriceStatus(priceStatus)
props.updateMaxFee(maxFee)
props.updateBaseFeePerGas(props.network.lastBlock.baseFeePerGas)
})
}
const onGasPriceChange = (value: string) => {
const gasPrice = value
props.setNewGasPrice(gasPrice, (txFeeText, priceStatus) => {
props.setTxFeeContent(txFeeText)
props.updateGasPriceStatus(priceStatus)
props.updateGasPrice(gasPrice)
})
}
return (
<div>
<div className="text-dark">You are about to create a transaction on {props.network.name} Network. Confirm the details to send the info to your provider.
<br />The provider for many users is MetaMask. The provider will ask you to sign the transaction before it is sent to {props.network.name} Network.
</div>
<div className="mt-3">
<div>
<span className="text-dark mr-2">From:</span>
<span>{props.tx.from}</span>
</div>
<div>
<span className="text-dark mr-2">To:</span>
<span>{props.tx.to ? props.tx.to : '(Contract Creation)'}</span>
</div>
<div className="d-flex align-items-center">
<span className="text-dark mr-2">Data:</span>
<pre className="udapp_wrapword mb-0">{props.tx.data && props.tx.data.length > 50 ? props.tx.data.substring(0, 49) + '...' : props.tx.data}
<CopyToClipboard content={props.tx.data} />
</pre>
</div>
<div className="mb-3">
<span className="text-dark mr-2">Amount:</span>
<span>{props.amount} Ether</span>
</div>
<div>
<span className="text-dark mr-2">Gas estimation:</span>
<span>{props.gasEstimation}</span>
</div>
<div>
<span className="text-dark mr-2">Gas limit:</span>
<span>${props.tx.gas}</span>
</div>
{
props.network.lastBlock.baseFeePerGas
? <div>
<div className="align-items-center my-1" title="Represents the part of the tx fee that goes to the miner.">
<div className='d-flex'>
<span className="text-dark mr-2 text-nowrap">Max Priority fee:</span>
<input className="form-control mr-1 text-right" style={{ height: '1.2rem', width: '6rem' }} value="1" id='maxpriorityfee' />
<span title="visit https://ethgasstation.info for current gas price info.">Gwei</span>
</div>
</div>
<div className="align-items-center my-1" title="Represents the maximum amount of fee that you will pay for this transaction. The minimun needs to be set to base fee.">
<div className='d-flex'>
<span className="text-dark mr-2 text-nowrap">Max fee (Not less than base fee {Web3.utils.fromWei(Web3.utils.toBN(parseInt(props.network.lastBlock.baseFeePerGas, 16)), 'Gwei')} Gwei):</span>
<input className="form-control mr-1 text-right" style={{ height: '1.2rem', width: '6rem' }} id='maxfee' onInput={(e) => onMaxFeeChange(e.target.value)} />
<span>Gwei</span>
<span className="text-dark ml-2"></span>
</div>
</div>
</div>
: <div className="d-flex align-items-center my-1">
<span className="text-dark mr-2 text-nowrap">Gas price:</span>
<input className="form-control mr-1 text-right" style={{ width: '40px', height: '28px' }} id='gasprice' onInput={(e) => onGasPriceChange(e.target.value)} />
<span>Gwei (visit <a target='_blank' href='https://ethgasstation.info'>ethgasstation.info</a> for current gas price info.)</span>
</div>
}
<div className="mb-3">
<span className="text-dark mr-2">Max transaction fee:</span>
<span className="text-warning" id='txfee'>{ props.txFeeContent }</span>
</div>
</div>
<div className="d-flex py-1 align-items-center custom-control custom-checkbox remixui_checkbox">
<input className="form-check-input custom-control-input" id="confirmsetting" type="checkbox" />
<label className="m-0 form-check-label custom-control-label" htmlFor="confirmsetting">Do not show this warning again.</label>
</div>
</div>
)
}

@ -496,4 +496,14 @@
align-items: center;
margin-left: 2%
}
#confirmsetting {
z-index: 1;
}
.udapp_wrapword {
white-space: pre-wrap; /* Since CSS 2.1 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}

@ -54,7 +54,13 @@ export interface RunTabState {
isSuccessful: boolean,
error: string
},
ipfsChecked: boolean
ipfsChecked: boolean,
gasPriceStatus: boolean,
confirmSettings: boolean,
maxFee: string,
maxPriorityFee: string,
baseFeePerGas: string,
txFeeContent: string
}
export const runTabInitialState: RunTabState = {
@ -124,7 +130,13 @@ export const runTabInitialState: RunTabState = {
isSuccessful: false,
error: null
},
ipfsChecked: false
ipfsChecked: false,
gasPriceStatus: false,
confirmSettings: false,
maxFee: '',
maxPriorityFee: '',
baseFeePerGas: '',
txFeeContent: ''
}
export const runTabReducer = (state: RunTabState = runTabInitialState, action: Action) => {
@ -441,6 +453,69 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
}
}
case 'SET_GAS_PRICE_STATUS': {
const payload: boolean = action.payload
return {
...state,
gasPriceStatus: payload
}
}
case 'SET_CONFIRM_SETTINGS': {
const payload: boolean = action.payload
return {
...state,
confirmSettings: payload
}
}
case 'SET_MAX_FEE': {
const payload: string = action.payload
return {
...state,
maxFee: payload
}
}
case 'SET_MAX_PRIORITY_FEE': {
const payload: string = action.payload
return {
...state,
maxPriorityFee: payload
}
}
case 'SET_BASE_FEE_PER_GAS': {
const payload: string = action.payload
return {
...state,
baseFeePerGas: payload
}
}
case 'SET_GAS_PRICE': {
const payload: string = action.payload
return {
...state,
gasPrice: payload
}
}
case 'SET_TX_FEE_CONTENT': {
const payload: string = action.payload
return {
...state,
txFeeContent: payload
}
}
default:
return state
}

@ -7,10 +7,23 @@ import { ContractDropdownUI } from './components/contractDropdownUI'
import { InstanceContainerUI } from './components/instanceContainerUI'
import { RecorderUI } from './components/recorderCardUI'
import { SettingsUI } from './components/settingsUI'
import { Modal, RunTabProps } from './types'
import { ContractData, Modal, RunTabProps } from './types'
import { runTabInitialState, runTabReducer } from './reducers/runTab'
import { initRunTab, setAccount, setUnit, setGasFee, setExecutionContext, setWeb3Endpoint, clearPopUp, createNewBlockchainAccount, setPassphrasePrompt, setMatchPassphrasePrompt, signMessageWithAddress, getSelectedContract, createInstance } from './actions'
import {
initRunTab, setAccount,
setUnit, setGasFee,
setExecutionContext, setWeb3Endpoint,
clearPopUp, createNewBlockchainAccount,
setPassphrasePrompt, setMatchPassphrasePrompt,
signMessageWithAddress, getSelectedContract,
createInstance, setCheckIpfs,
updateBaseFeePerGas, updateConfirmSettings,
updateGasPrice, updateGasPriceStatus,
updateMaxFee, updateMaxPriorityFee,
updateTxFeeContent
} from './actions'
import './css/run-tab.css'
import { PublishToStorage } from '@remix-ui/publish-to-storage'
export function RunTabUI (props: RunTabProps) {
const { plugin } = props
@ -26,6 +39,13 @@ export function RunTabUI (props: RunTabProps) {
const [modals, setModals] = useState<Modal[]>([])
const [focusToaster, setFocusToaster] = useState<string>('')
const [toasters, setToasters] = useState<string[]>([])
const [publishData, setPublishData] = useState<{
storage: 'ipfs' | 'swarm',
contract: ContractData
}>({
storage: null,
contract: null
})
const [runTab, dispatch] = useReducer(runTabReducer, runTabInitialState)
const REACT_API = { runTab }
@ -108,6 +128,20 @@ export function RunTabUI (props: RunTabProps) {
})
}
const resetStorage = () => {
setPublishData({
storage: null,
contract: null
})
}
const publishToStorage = (storage: 'ipfs' | 'swarm', contract: ContractData) => {
setPublishData({
storage,
contract
})
}
return (
<Fragment>
<div className="udapp_runTabView run-tab" id="runTabView" data-id="runTabView">
@ -143,6 +177,16 @@ export function RunTabUI (props: RunTabProps) {
passphrase={runTab.passphrase}
setPassphrase={setPassphrasePrompt}
createInstance={createInstance}
ipfsCheckedState={runTab.ipfsChecked}
setIpfsCheckedState={setCheckIpfs}
publishToStorage={publishToStorage}
updateBaseFeePerGas={updateBaseFeePerGas}
updateConfirmSettings={updateConfirmSettings}
updateGasPrice={updateGasPrice}
updateGasPriceStatus={updateGasPriceStatus}
updateMaxFee={updateMaxFee}
updateMaxPriorityFee={updateMaxPriorityFee}
updateTxFeeContent={updateTxFeeContent}
/>
<RecorderUI />
<InstanceContainerUI />
@ -150,6 +194,7 @@ export function RunTabUI (props: RunTabProps) {
</div>
<ModalDialog id='fileSystem' { ...focusModal } handleHide={ handleHideModal } />
<Toaster message={focusToaster} handleHide={handleToaster} />
<PublishToStorage api={props.plugin} resetStorage={resetStorage} storage={publishData.storage} contract={publishData.contract} />
</Fragment>
)
}

@ -101,6 +101,21 @@ export interface ValueProps {
sendUnit: string
}
export interface ContractData {
name: string,
contract: any,
compiler: any,
abi: any,
bytecodeObject: any,
bytecodeLinkReferences: any,
object: any,
deployedBytecode: any,
getConstructorInterface: () => any,
getConstructorInputs: () => any,
isOverSizeLimit: () => boolean,
metadata: any
}
export interface ContractDropdownProps {
exEnvironment: string,
contracts: {
@ -115,24 +130,21 @@ export interface ContractDropdownProps {
isSuccessful: boolean,
error: string
},
getSelectedContract: (contractName: string, compilerAtributeName: string) => {
name: string,
contract: string,
compiler: any,
abi: any,
bytecodeObject: any,
bytecodeLinkReferences: any,
object: any,
deployedBytecode: any,
getConstructorInterface: () => any,
getConstructorInputs: () => any,
isOverSizeLimit: () => boolean,
metadata: any
},
getSelectedContract: (contractName: string, compilerAtributeName: string) => ContractData,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void,
passphrase: string,
setPassphrase: (passphrase: string) => void,
createInstance: (gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, logBuilder: (msg: string) => JSX.Element) => void
createInstance: (selectedContract: ContractData, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, logBuilder: (msg: string) => JSX.Element, publishToStorage: (storage: 'ipfs' | 'swarm', contract: ContractData) => void) => void,
ipfsCheckedState: boolean,
setIpfsCheckedState: (value: boolean) => void,
publishToStorage: (storage: 'ipfs' | 'swarm', contract: ContractData) => void,
updateBaseFeePerGas: (baseFee: string) => void,
updateGasPriceStatus: (status: boolean) => void,
updateConfirmSettings: (confirmation: boolean) => void,
updateMaxFee: (fee: string) => void,
updateMaxPriorityFee: (fee: string) => void,
updateGasPrice: (price: string) => void,
updateTxFeeContent: (content: string) => void
}
export interface RecorderProps {

Loading…
Cancel
Save