diff --git a/libs/remix-ui/run-tab/src/lib/actions/custom.ts b/libs/remix-ui/run-tab/src/lib/actions/custom.ts deleted file mode 100644 index 7dacb97c10..0000000000 --- a/libs/remix-ui/run-tab/src/lib/actions/custom.ts +++ /dev/null @@ -1,204 +0,0 @@ -// eslint-disable-next-line no-unused-vars -import React from 'react' -import * as ethJSUtil from 'ethereumjs-util' -import Web3 from 'web3' -import { shortenAddress } from '@remix-ui/helper' -import { addProvider, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, removeProvider, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setNetworkName, setSelectedAccount, setSendUnit, setSendValue } from './payload' -import { runTabInitialState, runTabReducer } from '../reducers/runTab' - -// eslint-disable-next-line no-undef -export function useRunTabPlugin (plugin, executionContextModal: (executionContext: { context: string, fork: string }) => void) { - const [runTab, dispatch] = React.useReducer(runTabReducer, runTabInitialState) - - const setupEvents = () => { - plugin.blockchain.resetAndInit(plugin.config, { - getAddress: (cb) => { - cb(null, runTab.accounts.selectedAccount) - }, - getValue: (cb) => { - try { - const number = runTab.sendValue - const unit = runTab.sendUnit - - cb(null, Web3.utils.toWei(number, unit)) - } catch (e) { - cb(e) - } - }, - getGasLimit: (cb) => { - try { - cb(null, '0x' + new ethJSUtil.BN(runTab.gasLimit, 10).toString(16)) - } catch (e) { - cb(e.message) - } - } - }) - - plugin.blockchain.events.on('newTransaction', (tx, receipt) => { - plugin.emit('newTransaction', tx, receipt) - }) - - plugin.blockchain.event.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => { - if (!lookupOnly) dispatch(setSendValue(0)) - if (error) return - updateAccountBalances() - }) - - plugin.blockchain.event.register('contextChanged', (context, silent) => { - setFinalContext() - }) - - plugin.blockchain.event.register('networkStatus', ({ error, network }) => { - if (error) { - const netUI = 'can\'t detect network ' - setNetworkNameFromProvider(netUI) - - return - } - const networkProvider = plugin.networkModule.getNetworkProvider.bind(plugin.networkModule) - const netUI = (networkProvider() !== 'vm') ? `${network.name} (${network.id || '-'}) network` : '' - - setNetworkNameFromProvider(netUI) - }) - - plugin.blockchain.event.register('addProvider', provider => addExternalProvider(provider)) - plugin.blockchain.event.register('removeProvider', name => removeExternalProvider(name)) - plugin.on('manager', 'pluginActivated', addPluginProvider.bind(plugin)) - plugin.on('manager', 'pluginDeactivated', removePluginProvider.bind(plugin)) - - // setInterval(() => { - // fillAccountsList() - // }, 1000) - // fillAccountsList() - setTimeout(() => { - fillAccountsList() - }, 0) - } - - const updateAccountBalances = () => { - const accounts = runTab.accounts.loadedAccounts - - Object.keys(accounts).map((value) => { - plugin.blockchain.getBalanceInEther(value, (err, balance) => { - if (err) return - const updated = shortenAddress(value, balance) - - accounts[value] = updated - }) - }) - dispatch(fetchAccountsListSuccess(accounts)) - } - - const fillAccountsList = async () => { - try { - dispatch(fetchAccountsListRequest()) - const promise = plugin.blockchain.getAccounts() - - promise.then((accounts: string[]) => { - const loadedAccounts = {} - - if (!accounts) accounts = [] - accounts.forEach((account) => { - plugin.blockchain.getBalanceInEther(account, (err, balance) => { - if (err) return - const updated = shortenAddress(account, balance) - - loadedAccounts[account] = updated - }) - }) - dispatch(fetchAccountsListSuccess(loadedAccounts)) - }).catch((e) => { - dispatch(fetchAccountsListFailed(e.message)) - }) - } catch (e) { - // addTooltip(`Cannot get account list: ${e}`) - } - } - - const setAccount = (account: string) => { - dispatch(setSelectedAccount(account)) - } - - const setUnit = (unit: 'ether' | 'finney' | 'gwei' | 'wei') => { - dispatch(setSendUnit(unit)) - } - - const setGasFee = (value: number) => { - dispatch(setGasLimit(value)) - } - - const addPluginProvider = (profile) => { - if (profile.kind === 'provider') { - ((profile, app) => { - const web3Provider = { - async sendAsync (payload, callback) { - try { - const result = await app.call(profile.name, 'sendAsync', payload) - callback(null, result) - } catch (e) { - callback(e) - } - } - } - app.blockchain.addProvider({ name: profile.displayName, provider: web3Provider }) - })(profile, plugin) - } - } - - const removePluginProvider = (profile) => { - if (profile.kind === 'provider') plugin.blockchain.removeProvider(profile.displayName) - } - - const setFinalContext = () => { - // set the final context. Cause it is possible that this is not the one we've originaly selected - const value = _getProviderDropdownValue() - - setExecEnv(value) - // this.event.trigger('clearInstance', []) - } - - const _getProviderDropdownValue = (): string => { - const provider = plugin.blockchain.getProvider() - const fork = plugin.blockchain.getCurrentFork() - - return provider === 'vm' ? provider + '-' + fork : provider - } - - const setExecEnv = (env: string) => { - dispatch(setExecutionEnvironment(env)) - } - - const setNetworkNameFromProvider = (networkName: string) => { - dispatch(setNetworkName(networkName)) - } - - const addExternalProvider = (network) => { - dispatch(addProvider(network)) - // addTooltip(yo`${network.name} provider added`) - } - - const removeExternalProvider = (name) => { - dispatch(removeProvider(name)) - } - - const setProviderFromEndpoint = (executionContext: { context: string, fork: string }) => { - plugin.blockchain.setProviderFromEndpoint(plugin.REACT_API.externalEndpoint, executionContext, (alertMsg) => { - // if (alertMsg) addTooltip(alertMsg) - setFinalContext() - }) - } - - const setExecutionContext = (executionContext: { context: string, fork: string }) => { - plugin.blockchain.changeExecutionContext(executionContext, () => { - executionContextModal(executionContext) - }, (alertMsg) => { - // addTooltip(alertMsg) - }, setFinalContext()) - } - - const setWeb3Endpoint = (endpoint: string) => { - dispatch(setExternalEndpoint(endpoint)) - } - - return { runTab, setupEvents, fillAccountsList, setAccount, setUnit, setGasFee, setExecEnv, setFinalContext, setExecutionContext, setProviderFromEndpoint, setWeb3Endpoint } -} diff --git a/libs/remix-ui/run-tab/src/lib/actions/index.ts b/libs/remix-ui/run-tab/src/lib/actions/index.ts index df91f393c4..4159ec33a0 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/index.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/index.ts @@ -3,12 +3,12 @@ import React from 'react' import * as ethJSUtil from 'ethereumjs-util' import Web3 from 'web3' import { shortenAddress } from '@remix-ui/helper' -import { addProvider, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, removeProvider, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setNetworkName, setSelectedAccount, setSendUnit, setSendValue } from './payload' -import { Udapp } from '../types' +import { addProvider, displayNotification, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, removeProvider, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setNetworkName, setSelectedAccount, setSendUnit, setSendValue } from './payload' +import { RunTab } from '../types/run-tab' -let plugin: Udapp, dispatch: React.Dispatch +let plugin: RunTab, dispatch: React.Dispatch -export const initRunTab = (udapp: Udapp) => async (reducerDispatch: React.Dispatch) => { +export const initRunTab = (udapp: RunTab) => async (reducerDispatch: React.Dispatch) => { plugin = udapp dispatch = reducerDispatch setupEvents() @@ -80,7 +80,7 @@ const setupEvents = () => { } const updateAccountBalances = () => { - const accounts = runTab.accounts.loadedAccounts + const accounts = plugin.REACT_API.accounts.loadedAccounts Object.keys(accounts).map((value) => { plugin.blockchain.getBalanceInEther(value, (err, balance) => { @@ -119,15 +119,15 @@ const fillAccountsList = async () => { } } -const setAccount = (account: string) => { +export const setAccount = (account: string) => { dispatch(setSelectedAccount(account)) } -const setUnit = (unit: 'ether' | 'finney' | 'gwei' | 'wei') => { +export const setUnit = (unit: 'ether' | 'finney' | 'gwei' | 'wei') => { dispatch(setSendUnit(unit)) } -const setGasFee = (value: number) => { +export const setGasFee = (value: number) => { dispatch(setGasLimit(value)) } @@ -185,21 +185,20 @@ const removeExternalProvider = (name) => { dispatch(removeProvider(name)) } -const setProviderFromEndpoint = (executionContext: { context: string, fork: string }) => { - plugin.blockchain.setProviderFromEndpoint(runTab.externalEndpoint, executionContext, (alertMsg) => { - // if (alertMsg) addTooltip(alertMsg) - setFinalContext() - }) -} - -const setExecutionContext = (executionContext: { context: string, fork: string }) => { +// eslint-disable-next-line no-undef +export const setExecutionContext = (executionContext: { context: string, fork: string }, displayContent: JSX.Element) => { plugin.blockchain.changeExecutionContext(executionContext, () => { - executionContextModal(executionContext) + dispatch(displayNotification('External node request', displayContent, 'OK', 'Cancel', () => { + plugin.blockchain.setProviderFromEndpoint(plugin.REACT_API.externalEndpoint, executionContext, (alertMsg) => { + // if (alertMsg) addTooltip(alertMsg) + setFinalContext() + }) + }, () => { setFinalContext() })) }, (alertMsg) => { // addTooltip(alertMsg) }, setFinalContext()) } -const setWeb3Endpoint = (endpoint: string) => { +export const setWeb3Endpoint = (endpoint: string) => { dispatch(setExternalEndpoint(endpoint)) } diff --git a/libs/remix-ui/run-tab/src/lib/actions/payload.ts b/libs/remix-ui/run-tab/src/lib/actions/payload.ts index a527f34b4a..ea21748146 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/payload.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/payload.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-undef */ export const fetchAccountsListRequest = () => { return { type: 'FETCH_ACCOUNTS_LIST_REQUEST', @@ -82,7 +83,7 @@ export const removeProvider = (provider: string) => { } } -export const displayNotification = (title: string, message: string, labelOk: string, labelCancel: string, actionOk?: (...args) => void, actionCancel?: (...args) => void) => { +export const displayNotification = (title: string, message: string | JSX.Element, labelOk: string, labelCancel: string, actionOk?: (...args) => void, actionCancel?: (...args) => void) => { return { type: 'DISPLAY_NOTIFICATION', payload: { title, message, labelOk, labelCancel, actionOk, actionCancel } diff --git a/libs/remix-ui/run-tab/src/lib/components/environment.tsx b/libs/remix-ui/run-tab/src/lib/components/environment.tsx index 473fba234c..3c91ed9741 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -3,14 +3,53 @@ import React from 'react' import { EnvironmentProps } from '../types' export function EnvironmentUI (props: EnvironmentProps) { + const handleInputEndpoint = (e: any) => { + props.setWeb3Endpoint(e.target.value) + } + const handleChangeExEnv = (env: string) => { const provider = props.providers.providerList.find(exEnv => exEnv.value === env) const fork = provider.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' - props.setExecutionContext({ context, fork }) - props.setExecEnv(env) + const displayContent = web3ProviderDialogBody() + + props.setExecutionContext({ context, fork }, displayContent) + } + + const web3ProviderDialogBody = () => { + const thePath = '' + + return ( + <> +
+ Note: To use Geth & https://remix.ethereum.org, configure it to allow requests from Remix:(see Geth Docs on rpc server) +
geth --http --http.corsdomain https://remix.ethereum.org
+
+ To run Remix & a local Geth test node, use this command: (see Geth Docs on Dev mode) +
geth --http --http.corsdomain="${window.origin}" --http.api web3,eth,debug,personal,net --vmdebug --datadir ${thePath} --dev console
+
+
+ WARNING: It is not safe to use the --http.corsdomain flag with a wildcard: --http.corsdomain * +
+
For more info: Remix Docs on Web3 Provider +
+
+ Web3 Provider Endpoint +
+ + + ) } return ( diff --git a/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx b/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx index c100c1e120..45c94f5e97 100644 --- a/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx @@ -87,7 +87,7 @@ export function SettingsUI (props: SettingsProps) { return (
- + diff --git a/libs/remix-ui/run-tab/src/lib/run-tab.tsx b/libs/remix-ui/run-tab/src/lib/run-tab.tsx index d07cbbb62b..edf41f8a68 100644 --- a/libs/remix-ui/run-tab/src/lib/run-tab.tsx +++ b/libs/remix-ui/run-tab/src/lib/run-tab.tsx @@ -1,19 +1,19 @@ // eslint-disable-next-line no-use-before-define -import React, { Fragment, useEffect, useState } from 'react' +import React, { Fragment, useEffect, useReducer, useState } from 'react' import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-next-line no-unused-vars import { Toaster } from '@remix-ui/toaster' -import { useRunTabPlugin } from './actions/custom' 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 { runTabInitialState, runTabReducer } from './reducers/runTab' +import { initRunTab, setAccount, setUnit, setGasFee, setExecutionContext, setWeb3Endpoint } from './actions' import './css/run-tab.css' export function RunTabUI (props: RunTabProps) { - const { runTab, setupEvents, setAccount, setUnit, setGasFee, setExecEnv, setExecutionContext, setProviderFromEndpoint, setFinalContext, setWeb3Endpoint } = useRunTabPlugin(props.plugin, executionContextModal) + const { plugin } = props const [focusModal, setFocusModal] = useState({ hide: true, title: '', @@ -24,11 +24,16 @@ export function RunTabUI (props: RunTabProps) { cancelFn: () => {} }) const [modals, setModals] = useState([]) + const [runTab, dispatch] = useReducer(runTabReducer, runTabInitialState) const REACT_API = { runTab } useEffect(() => { - setupEvents() - }, []) + initRunTab(plugin)(dispatch) + }, [plugin]) + + useEffect(() => { + plugin.onReady(runTab) + }, [REACT_API]) useEffect(() => { if (modals.length > 0) { @@ -57,10 +62,6 @@ export function RunTabUI (props: RunTabProps) { } }, [runTab.notification]) - useEffect(() => { - props.plugin.onReady(runTab) - }, [REACT_API]) - // eslint-disable-next-line no-undef const modal = (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => { setModals(modals => { @@ -75,53 +76,25 @@ export function RunTabUI (props: RunTabProps) { }) } - const handleInputEndpoint = (e: any) => { - setWeb3Endpoint(e.target.value) - } - - function executionContextModal (executionContext: { context: string, fork: string }) { - modal('External node request', web3ProviderDialogBody(), 'OK', () => { setProviderFromEndpoint(executionContext) }, 'Cancel', () => { setFinalContext() }) - } - - const web3ProviderDialogBody = () => { - const thePath = '' - - return ( - <> -
- Note: To use Geth & https://remix.ethereum.org, configure it to allow requests from Remix:(see Geth Docs on rpc server) -
geth --http --http.corsdomain https://remix.ethereum.org
-
- To run Remix & a local Geth test node, use this command: (see Geth Docs on Dev mode) -
geth --http --http.corsdomain="${window.origin}" --http.api web3,eth,debug,personal,net --vmdebug --datadir ${thePath} --dev console
-
-
- WARNING: It is not safe to use the --http.corsdomain flag with a wildcard: --http.corsdomain * -
-
For more info: Remix Docs on Web3 Provider -
-
- Web3 Provider Endpoint -
- - - ) - } - return (
- + diff --git a/libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts b/libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts index 39a9292a0f..bd19058d4a 100644 --- a/libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts +++ b/libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts @@ -19,7 +19,7 @@ export class Blockchain extends Plugin { providers: {}; getCurrentProvider(): any; /** Return the list of accounts */ - getAccounts(cb: any): any; + getAccounts(cb?: any): any; deployContractAndLibraries(selectedContract: any, args: any, contractMetadata: any, compilerContracts: any, callbacks: any, confirmationCb: any): void; deployContractWithLibrary(selectedContract: any, args: any, contractMetadata: any, compilerContracts: any, callbacks: any, confirmationCb: any): void; createContract(selectedContract: any, data: any, continueCb: any, promptCb: any, confirmationCb: any, finalCb: any): void; diff --git a/libs/remix-ui/run-tab/src/lib/types/index.ts b/libs/remix-ui/run-tab/src/lib/types/index.ts index d2b19b5577..4aa70d5304 100644 --- a/libs/remix-ui/run-tab/src/lib/types/index.ts +++ b/libs/remix-ui/run-tab/src/lib/types/index.ts @@ -1,13 +1,7 @@ -import { RunTabState } from '../reducers/runTab' -import { Blockchain } from './blockchain' - -export interface Udapp { - onReady: (api: RunTabState) => void, - REACT_API: RunTabState, - blockchain: Blockchain -} +/* eslint-disable no-undef */ +import { RunTab } from './run-tab' export interface RunTabProps { - plugin: Udapp + plugin: RunTab } export interface SettingsProps { @@ -25,7 +19,7 @@ export interface SettingsProps { sendUnit: string, gasLimit: number, setGasFee: (value: number) => void, - setExecEnv: (env: string) => void, + setWeb3Endpoint: (endpoint: string) => void, personalMode: boolean, networkName: string, providers: { @@ -41,11 +35,12 @@ export interface SettingsProps { isSuccessful: boolean, error: string }, - setExecutionContext: (executionContext: { context: string, fork: string }) => void + setExecutionContext: (executionContext: { context: string, fork: string }, displayContent: JSX.Element) => void, + externalEndpoint: string } export interface EnvironmentProps { - setExecEnv: (env: string) => void, + setWeb3Endpoint: (endpoint: string) => void, selectedEnv: string, providers: { providerList: { @@ -60,7 +55,8 @@ export interface EnvironmentProps { isSuccessful: boolean, error: string }, - setExecutionContext: (executionContext: { context: string, fork: string }) => void + setExecutionContext: (executionContext: { context: string, fork: string }, displayContent: JSX.Element) => void, + externalEndpoint: string } export interface NetworkProps { diff --git a/libs/remix-ui/run-tab/src/lib/types/run-tab.d.ts b/libs/remix-ui/run-tab/src/lib/types/run-tab.d.ts new file mode 100644 index 0000000000..a1c50e6495 --- /dev/null +++ b/libs/remix-ui/run-tab/src/lib/types/run-tab.d.ts @@ -0,0 +1,41 @@ +export class RunTab extends ViewPlugin { + constructor(blockchain: any, config: any, fileManager: any, editor: any, filePanel: any, compilersArtefacts: any, networkModule: any, mainView: any, fileProvider: any); + event: any; + config: any; + blockchain: Blockchain; + fileManager: any; + editor: any; + logCallback: (msg: any) => void; + filePanel: any; + compilersArtefacts: any; + networkModule: any; + fileProvider: any; + REACT_API: RunTabState; + el: HTMLDivElement; + setupEvents(): void; + getSettings(): any; + setEnvironmentMode(env: any): Promise; + createVMAccount(newAccount: any): any; + sendTransaction(tx: any): any; + getAccounts(cb: any): any; + pendingTransactionsCount(): any; + renderInstanceContainer(): void; + instanceContainer: any; + noInstancesText: any; + renderSettings(): void; + settingsUI: any; + renderDropdown(udappUI: any, fileManager: any, compilersArtefacts: any, config: any, editor: any, logCallback: any): void; + contractDropdownUI: any; + renderRecorder(udappUI: any, fileManager: any, config: any, logCallback: any): void; + recorderCount: any; + recorderInterface: any; + renderRecorderCard(): void; + recorderCard: any; + udappUI: any; + renderComponent(): void; + onReady(api: any): void; +} +import { ViewPlugin } from "@remixproject/engine-web/lib/view"; +import { Blockchain } from "./blockchain"; +import { RunTabState } from "../reducers/runTab"; +