diff --git a/apps/etherscan/src/app/AppContext.tsx b/apps/etherscan/src/app/AppContext.tsx index f121406a679..69d967534d2 100644 --- a/apps/etherscan/src/app/AppContext.tsx +++ b/apps/etherscan/src/app/AppContext.tsx @@ -20,5 +20,6 @@ export const AppContext = React.createContext({ themeType: 'dark' as ThemeType, setThemeType: (themeType: ThemeType) => { console.log('Calling Set Theme Type') - } + }, + networkName: '' }) diff --git a/apps/etherscan/src/app/RemixPlugin.tsx b/apps/etherscan/src/app/EtherscanPluginClient.ts similarity index 80% rename from apps/etherscan/src/app/RemixPlugin.tsx rename to apps/etherscan/src/app/EtherscanPluginClient.ts index 59967c5e41a..ec545f806ea 100644 --- a/apps/etherscan/src/app/RemixPlugin.tsx +++ b/apps/etherscan/src/app/EtherscanPluginClient.ts @@ -1,10 +1,21 @@ import {PluginClient} from '@remixproject/plugin' +import { createClient } from '@remixproject/plugin-webview' import {verify, EtherScanReturn} from './utils/verify' import {getReceiptStatus, getEtherScanApi, getNetworkName, getProxyContractReceiptStatus} from './utils' +import EventManager from 'events' -export class RemixClient extends PluginClient { - loaded() { - return this.onload() +export class EtherscanPluginClient extends PluginClient { + public internalEvents: EventManager + + constructor() { + super() + createClient(this) + this.internalEvents = new EventManager() + this.onload() + } + + onActivation(): void { + this.internalEvents.emit('etherscan_activated') } async verify( diff --git a/apps/etherscan/src/app/app.tsx b/apps/etherscan/src/app/app.tsx index 972413f7f2b..39e89e00d7e 100644 --- a/apps/etherscan/src/app/app.tsx +++ b/apps/etherscan/src/app/app.tsx @@ -2,8 +2,7 @@ import React, {useState, useEffect, useRef} from 'react' import {CompilationFileSources, CompilationResult} from '@remixproject/plugin-api' -import {RemixClient} from './RemixPlugin' -import {createClient} from '@remixproject/plugin-webview' +import { EtherscanPluginClient } from './EtherscanPluginClient' import {AppContext} from './AppContext' import {DisplayRoutes} from './routes' @@ -21,32 +20,29 @@ export const getNewContractNames = (compilationResult: CompilationResult) => { for (const file of Object.keys(compiledContracts)) { const newContractNames = Object.keys(compiledContracts[file]) + result = [...result, ...newContractNames] } return result } +const plugin = new EtherscanPluginClient() + const App = () => { const [apiKey, setAPIKey] = useLocalStorage('apiKey', '') - const [clientInstance, setClientInstance] = useState(undefined as any) - const [receipts, setReceipts] = useLocalStorage('receipts', []) - const [contracts, setContracts] = useState([] as string[]) - const [themeType, setThemeType] = useState('dark' as ThemeType) + const [receipts, setReceipts] = useLocalStorage('receipts', []) + const [contracts, setContracts] = useState([]) + const [themeType, setThemeType] = useState('dark') + const [networkName, setNetworkName] = useState('Loading...') const timer = useRef(null) - - const clientInstanceRef = useRef(clientInstance) - clientInstanceRef.current = clientInstance const contractsRef = useRef(contracts) + contractsRef.current = contracts useEffect(() => { - const client = new RemixClient() - createClient(client) - const loadClient = async () => { - await client.onload() - setClientInstance(client) - client.on('solidity', 'compilationFinished', (fileName: string, source: CompilationFileSources, languageVersion: string, data: CompilationResult) => { + plugin.internalEvents.on('etherscan_activated', () => { + plugin.on('solidity', 'compilationFinished', (fileName: string, source: CompilationFileSources, languageVersion: string, data: CompilationResult) => { const newContractsNames = getNewContractNames(data) const newContractsToSave: string[] = [...contractsRef.current, ...newContractsNames] @@ -55,21 +51,16 @@ const App = () => { setContracts(uniqueContracts) }) - - //const currentTheme = await client.call("theme", "currentTheme") - //setThemeType(currentTheme.quality) - //client.on("theme", "themeChanged", (theme) => { - // setThemeType(theme.quality) - //}) - } - - loadClient() + plugin.on('blockchain' as any, 'networkStatus', (result) => { + setNetworkName(`${result.network.name} ${result.network.id !== '-' ? `(Chain id: ${result.network.id})` : '(Not supported)'}`) + }) + // @ts-ignore + plugin.call('blockchain', 'getCurrentNetworkStatus').then((result: any) => setNetworkName(`${result.network.name} ${result.network.id !== '-' ? `(Chain id: ${result.network.id})` : '(Not supported)'}`)) + }) }, []) useEffect(() => { - let receiptsNotVerified: Receipt[] = receipts.filter((item: Receipt) => { - return item.status === 'Pending in queue' || item.status === 'Max rate limit reached' - }) + let receiptsNotVerified: Receipt[] = receipts.filter((item: Receipt) => item.status === 'Pending in queue' || item.status === 'Max rate limit reached') if (receiptsNotVerified.length > 0) { if (timer.current) { @@ -77,15 +68,12 @@ const App = () => { timer.current = null } timer.current = setInterval(async () => { - const {network, networkId} = await getNetworkName(clientInstanceRef.current) - if (!clientInstanceRef.current) { - return - } + const {network, networkId} = await getNetworkName(plugin) - if (network === 'vm') { - return - } + if (!plugin) return + if (network === 'vm') return let newReceipts = receipts + for (const item of receiptsNotVerified) { await new Promise((r) => setTimeout(r, 500)) // avoid api rate limit exceed. let status @@ -110,9 +98,7 @@ const App = () => { }) } } - receiptsNotVerified = newReceipts.filter((item: Receipt) => { - return item.status === 'Pending in queue' || item.status === 'Max rate limit reached' - }) + receiptsNotVerified = newReceipts.filter((item: Receipt) => item.status === 'Pending in queue' || item.status === 'Max rate limit reached') if (timer.current && receiptsNotVerified.length === 0) { clearInterval(timer.current) timer.current = null @@ -127,16 +113,17 @@ const App = () => { value={{ apiKey, setAPIKey, - clientInstance, + clientInstance: plugin, receipts, setReceipts, contracts, setContracts, themeType, - setThemeType + setThemeType, + networkName }} > - + { plugin && } ) } diff --git a/apps/etherscan/src/app/views/HomeView.tsx b/apps/etherscan/src/app/views/HomeView.tsx index e9db144bd18..c08a021f99d 100644 --- a/apps/etherscan/src/app/views/HomeView.tsx +++ b/apps/etherscan/src/app/views/HomeView.tsx @@ -10,7 +10,7 @@ import {VerifyView} from './VerifyView' export const HomeView: React.FC = () => { return ( - {({apiKey, clientInstance, setReceipts, receipts, contracts}) => { + {({apiKey, clientInstance, setReceipts, receipts, contracts, networkName}) => { return !apiKey ? ( { const newReceipts = [...receipts, receipt] setReceipts(newReceipts) }} + networkName={networkName} /> ) }} diff --git a/apps/etherscan/src/app/views/VerifyView.tsx b/apps/etherscan/src/app/views/VerifyView.tsx index adfd0e6cfb0..ab6e7c641ca 100644 --- a/apps/etherscan/src/app/views/VerifyView.tsx +++ b/apps/etherscan/src/app/views/VerifyView.tsx @@ -14,7 +14,8 @@ interface Props { client: PluginClient apiKey: string onVerifiedContract: (receipt: Receipt) => void - contracts: string[] + contracts: string[], + networkName: string } interface FormValues { @@ -23,27 +24,14 @@ interface FormValues { expectedImplAddress?: string } -export const VerifyView: React.FC = ({apiKey, client, contracts, onVerifiedContract}) => { +export const VerifyView: React.FC = ({apiKey, client, contracts, onVerifiedContract, networkName}) => { const [results, setResults] = useState('') - const [networkName, setNetworkName] = useState('Loading...') const [selectedContract, setSelectedContract] = useState('') const [showConstructorArgs, setShowConstructorArgs] = useState(false) const [isProxyContract, setIsProxyContract] = useState(false) const [constructorInputs, setConstructorInputs] = useState([]) const verificationResult = useRef({}) - useEffect(() => { - if (client && client.on) { - client.on('blockchain' as any, 'networkStatus', (result) => { - setNetworkName(`${result.network.name} ${result.network.id !== '-' ? `(Chain id: ${result.network.id})` : '(Not supported)'}`) - }) - } - return () => { - // To fix memory leak - if (client && client.off) client.off('blockchain' as any, 'networkStatus') - } - }, [client]) - useEffect(() => { if (contracts.includes(selectedContract)) updateConsFields(selectedContract) }, [contracts]) diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index 779ea27f0a7..d3f667de1d9 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -23,7 +23,7 @@ const profile = { name: 'blockchain', displayName: 'Blockchain', description: 'Blockchain - Logic', - methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider', 'getCurrentFork', 'getAccounts', 'web3VM', 'web3', 'getProvider'], + methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider', 'getCurrentFork', 'getAccounts', 'web3VM', 'web3', 'getProvider', 'getCurrentNetworkStatus'], version: packageJson.version }