From 5760306ed6785d2ab7b815129aca2184745fa2c6 Mon Sep 17 00:00:00 2001 From: Romashka Date: Sun, 15 Dec 2024 01:05:26 +0200 Subject: [PATCH 01/35] typo-Update app.tsx --- apps/circuit-compiler/src/app/app.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/circuit-compiler/src/app/app.tsx b/apps/circuit-compiler/src/app/app.tsx index 6d845b2e8e..b39b3cddc7 100644 --- a/apps/circuit-compiler/src/app/app.tsx +++ b/apps/circuit-compiler/src/app/app.tsx @@ -144,7 +144,7 @@ function App() { dispatch({ type: 'SET_COMPILER_FEEDBACK', payload: report }) } catch (e) { - if (process.platform === 'win32' && err.message.includes('3221225781')) return dispatch({ type: 'SET_COMPILER_FEEDBACK', payload: 'The compiler failed to start because of some missing dependecies. Please install or repair the Microsoft Visual C++ Redistributable package to resolve this issue.' }) + if (process.platform === 'win32' && err.message.includes('3221225781')) return dispatch({ type: 'SET_COMPILER_FEEDBACK', payload: 'The compiler failed to start because of some missing dependencies. Please install or repair the Microsoft Visual C++ Redistributable package to resolve this issue.' }) dispatch({ type: 'SET_COMPILER_FEEDBACK', payload: err.message }) } } From 84c338785ff3f23b2c54094048beeac7f580aedd Mon Sep 17 00:00:00 2001 From: Romashka Date: Sun, 15 Dec 2024 01:06:12 +0200 Subject: [PATCH 02/35] typo-Update terminal.json --- apps/remix-dapp/src/locales/en/terminal.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-dapp/src/locales/en/terminal.json b/apps/remix-dapp/src/locales/en/terminal.json index 562ec9873c..a3d32452c9 100644 --- a/apps/remix-dapp/src/locales/en/terminal.json +++ b/apps/remix-dapp/src/locales/en/terminal.json @@ -15,7 +15,7 @@ "terminal.welcomeText8": "Right-click on a JavaScript file in the file explorer and then click `Run`", "terminal.welcomeText9": "The following libraries are accessible", "terminal.welcomeText10": "Type the library name to see available commands", - "terminal.text1": "This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.", + "terminal.text1": "This type of command has been deprecated and is not functioning anymore. Please run remix.help() to list available commands.", "terminal.hideTerminal": "Hide Terminal", "terminal.showTerminal": "Show Terminal", "terminal.clearConsole": "Clear console", From 7a74802e417337f4500b0cbc097d2f5b9d031823 Mon Sep 17 00:00:00 2001 From: Romashka Date: Sun, 15 Dec 2024 01:17:07 +0200 Subject: [PATCH 03/35] code-Update locale-module.js --- apps/remix-ide/src/app/tabs/locale-module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/locale-module.js b/apps/remix-ide/src/app/tabs/locale-module.js index 413fe9df35..f4b3252df1 100644 --- a/apps/remix-ide/src/app/tabs/locale-module.js +++ b/apps/remix-ide/src/app/tabs/locale-module.js @@ -38,7 +38,7 @@ export class LocaleModule extends Plugin { config: Registry.getInstance().get('config') && Registry.getInstance().get('config').api } this.locales = {} - locales.map((locale) => { + locales.forEach((locale) => { this.locales[locale.code.toLocaleLowerCase()] = locale }) this._paq = _paq From 28c0eb8abbf0090179b083d2b46e9b09a81c84a2 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 9 Dec 2024 16:43:26 +0530 Subject: [PATCH 04/35] save Vm state icon --- apps/remix-dapp/src/locales/en/udapp.json | 1 + apps/remix-ide/src/app/tabs/locales/en/udapp.json | 1 + libs/remix-ui/run-tab/src/lib/components/environment.tsx | 3 +++ 3 files changed, 5 insertions(+) diff --git a/apps/remix-dapp/src/locales/en/udapp.json b/apps/remix-dapp/src/locales/en/udapp.json index d8ade051f8..fadb2ed75b 100644 --- a/apps/remix-dapp/src/locales/en/udapp.json +++ b/apps/remix-dapp/src/locales/en/udapp.json @@ -63,6 +63,7 @@ "udapp._comment_environment.tsx": "libs/remix-ui/run-tab/src/lib/components/environment.tsx", "udapp.environment": "Environment", "udapp.environmentDocs": "Click for docs about Environment", + "udapp.saveVmState": "Save VM state", "udapp.tooltipText2": "Open chainlist.org and get the connection specs of the chain you want to interact with.", "udapp.tooltipText3": "Click to open a bridge for converting L1 mainnet ETH to the selected network currency.", diff --git a/apps/remix-ide/src/app/tabs/locales/en/udapp.json b/apps/remix-ide/src/app/tabs/locales/en/udapp.json index 8fe443a37f..d56d7087a7 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/udapp.json +++ b/apps/remix-ide/src/app/tabs/locales/en/udapp.json @@ -63,6 +63,7 @@ "udapp._comment_environment.tsx": "libs/remix-ui/run-tab/src/lib/components/environment.tsx", "udapp.environment": "Environment", "udapp.environmentDocs": "Click for docs about Environment", + "udapp.saveVmState": "Save VM state", "udapp.tooltipText2": "Open chainlist.org and get the connection specs of the chain you want to interact with.", "udapp.tooltipText3": "Click to open a bridge for converting L1 mainnet ETH to the selected network currency.", 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 a0428c42a1..8e304eed14 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -38,6 +38,9 @@ export function EnvironmentUI(props: EnvironmentProps) { + }> + +
From 7c796220c37bd1eae6e895ce0cb20b0e1932a4ca Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 9 Dec 2024 16:49:13 +0530 Subject: [PATCH 05/35] show icon only for VM --- libs/remix-ui/run-tab/src/lib/components/environment.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 8e304eed14..12cb4daf2e 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -38,9 +38,9 @@ export function EnvironmentUI(props: EnvironmentProps) { - }> + { currentProvider && currentProvider.isVM && }> - + }
From 50bc70a070ebc5cfd491bd7bdc8314f7ffd88021 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 9 Dec 2024 17:31:21 +0530 Subject: [PATCH 06/35] show modal --- apps/remix-dapp/src/locales/en/udapp.json | 2 ++ .../src/app/tabs/locales/en/udapp.json | 2 ++ .../src/lib/components/environment.tsx | 36 +++++++++++++++++-- .../run-tab/src/lib/components/settingsUI.tsx | 9 ++++- libs/remix-ui/run-tab/src/lib/types/index.ts | 1 + 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/apps/remix-dapp/src/locales/en/udapp.json b/apps/remix-dapp/src/locales/en/udapp.json index fadb2ed75b..431eb59ed4 100644 --- a/apps/remix-dapp/src/locales/en/udapp.json +++ b/apps/remix-dapp/src/locales/en/udapp.json @@ -49,6 +49,8 @@ "udapp.enterAMessageToSign": "Enter a message to sign", "udapp.hash": "hash", "udapp.signature": "signature", + "udapp.saveVmStateTitle": "Save VM state", + "udapp.saveVmStateLabel": "State Name", "udapp.injectedTitle": "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type).", "udapp.createNewAccount": "Create a new account", "udapp.web3Title": "Creating an account is possible only in Personal mode. Please go to Settings to enable it.", diff --git a/apps/remix-ide/src/app/tabs/locales/en/udapp.json b/apps/remix-ide/src/app/tabs/locales/en/udapp.json index d56d7087a7..f9c88dc1e6 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/udapp.json +++ b/apps/remix-ide/src/app/tabs/locales/en/udapp.json @@ -49,6 +49,8 @@ "udapp.enterAMessageToSign": "Enter a message to sign and click `Sign`", "udapp.hash": "hash", "udapp.signature": "signature", + "udapp.saveVmStateTitle": "Save VM state", + "udapp.saveVmStateLabel": "State Name", "udapp.injectedTitle": "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type).", "udapp.createNewAccount": "Create new account", "udapp.web3Title": "Creating an account is possible only in Personal mode. Please go to Settings to enable it.", 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 12cb4daf2e..fde65572a1 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -1,6 +1,6 @@ // eslint-disable-next-line no-use-before-define import React, { useEffect } from 'react' -import { FormattedMessage } from 'react-intl' +import { FormattedMessage, useIntl } from 'react-intl' import { EnvironmentProps, Provider } from '../types' import { Dropdown } from 'react-bootstrap' import { CustomMenu, CustomToggle, CustomTooltip } from '@remix-ui/helper' @@ -23,6 +23,38 @@ export function EnvironmentUI(props: EnvironmentProps) { 'L2 - Arbitrum': 'https://bridge.arbitrum.io/' } + const intl = useIntl() + + const saveVmStatePrompt = (defaultName: string) => { + return ( +
+ + +
+ ) + } + + const saveVmState = () => { + const defaultName: string = `${currentProvider.name}_${Date.now()}` + props.modal( + intl.formatMessage({ id: 'udapp.saveVmStateTitle' }), + saveVmStatePrompt(defaultName), + intl.formatMessage({ id: 'udapp.save' }), + () => { + console.log('Saved') + }, + intl.formatMessage({ id: 'udapp.cancel' }), + null + ) + } + const isL2 = (providerDisplayName: string) => providerDisplayName && (providerDisplayName.startsWith('L2 - Optimism') || providerDisplayName.startsWith('L2 - Arbitrum')) return (
@@ -39,7 +71,7 @@ export function EnvironmentUI(props: EnvironmentProps) { { currentProvider && currentProvider.isVM && }> - + }
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 12a7da58dd..44920f33f6 100644 --- a/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx @@ -12,7 +12,14 @@ export function SettingsUI(props: SettingsProps) { return (
- + void + modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void, okBtnClass?: string, cancelBtnClass?: string) => void, } export interface NetworkProps { From 90a4ad02e23315ffdf45d1e1dd7804aa0b8c47e4 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 9 Dec 2024 18:27:08 +0530 Subject: [PATCH 07/35] save state in file in FE --- .../src/lib/components/environment.tsx | 22 +++++++++++++------ .../run-tab/src/lib/components/settingsUI.tsx | 1 + libs/remix-ui/run-tab/src/lib/types/index.ts | 1 + 3 files changed, 17 insertions(+), 7 deletions(-) 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 fde65572a1..0a3643750d 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -1,11 +1,12 @@ // eslint-disable-next-line no-use-before-define -import React, { useEffect } from 'react' +import React, { useEffect, useRef } from 'react' import { FormattedMessage, useIntl } from 'react-intl' import { EnvironmentProps, Provider } from '../types' import { Dropdown } from 'react-bootstrap' import { CustomMenu, CustomToggle, CustomTooltip } from '@remix-ui/helper' export function EnvironmentUI(props: EnvironmentProps) { + const vmStateName = useRef('') Object.entries(props.providers.providerList.filter((provider) => { return provider.isVM })) Object.entries(props.providers.providerList.filter((provider) => { return provider.isInjected })) @@ -24,6 +25,7 @@ export function EnvironmentUI(props: EnvironmentProps) { } const intl = useIntl() + const isSaveEvmStateChecked = props.config.get('settings/save-evm-state') const saveVmStatePrompt = (defaultName: string) => { return ( @@ -33,22 +35,28 @@ export function EnvironmentUI(props: EnvironmentProps) { vmStateName.current = e.target.value} />
) } const saveVmState = () => { - const defaultName: string = `${currentProvider.name}_${Date.now()}` + const context = currentProvider.name + vmStateName.current = `${context}_${Date.now()}` props.modal( intl.formatMessage({ id: 'udapp.saveVmStateTitle' }), - saveVmStatePrompt(defaultName), + saveVmStatePrompt(vmStateName.current), intl.formatMessage({ id: 'udapp.save' }), - () => { - console.log('Saved') + async () => { + const contextExists = await props.runTabPlugin.call('fileManager', 'exists', `.states/${context}/state.json`) + if (contextExists) { + const currentStateDb = await props.runTabPlugin.call('fileManager', 'readFile', `.states/${context}/state.json`) + await props.runTabPlugin.call('fileManager', 'writeFile', `.states/saved_states/${vmStateName.current}.json`, currentStateDb) + } }, intl.formatMessage({ id: 'udapp.cancel' }), null @@ -70,7 +78,7 @@ export function EnvironmentUI(props: EnvironmentProps) { - { currentProvider && currentProvider.isVM && }> + { currentProvider && currentProvider.isVM && isSaveEvmStateChecked && }> } 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 44920f33f6..b3d9b28087 100644 --- a/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx @@ -19,6 +19,7 @@ export function SettingsUI(props: SettingsProps) { setExecutionContext={props.setExecutionContext} checkSelectionCorrectness={props.EvaluateEnvironmentSelection} modal={props.modal} + config={props.runTabPlugin.config} /> void modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void, okBtnClass?: string, cancelBtnClass?: string) => void, + config: any } export interface NetworkProps { From da5b57d9e0150636f1096b562259bebfc6faf361 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 10 Dec 2024 15:21:43 +0530 Subject: [PATCH 08/35] save timestamp --- libs/remix-ui/run-tab/src/lib/components/environment.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 0a3643750d..86b14528fc 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -54,8 +54,11 @@ export function EnvironmentUI(props: EnvironmentProps) { async () => { const contextExists = await props.runTabPlugin.call('fileManager', 'exists', `.states/${context}/state.json`) if (contextExists) { - const currentStateDb = await props.runTabPlugin.call('fileManager', 'readFile', `.states/${context}/state.json`) - await props.runTabPlugin.call('fileManager', 'writeFile', `.states/saved_states/${vmStateName.current}.json`, currentStateDb) + let currentStateDb = await props.runTabPlugin.call('fileManager', 'readFile', `.states/${context}/state.json`) + currentStateDb = JSON.parse(currentStateDb) + currentStateDb.savingTimestamp = Date.now() + await props.runTabPlugin.call('fileManager', 'writeFile', `.states/saved_states/${vmStateName.current}.json`, JSON.stringify(currentStateDb, null, 2)) + props.runTabPlugin.call('notification', 'toast', `VM state ${vmStateName.current} saved.`) } }, intl.formatMessage({ id: 'udapp.cancel' }), From b7366a5eb24ee7ec40176ee15c1706c6c8243433 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 10 Dec 2024 17:15:01 +0530 Subject: [PATCH 09/35] list saved states --- .../app/providers/environment-explorer.tsx | 42 +++++++++++++++++++ .../src/lib/components/environment.tsx | 1 + 2 files changed, 43 insertions(+) diff --git a/apps/remix-ide/src/app/providers/environment-explorer.tsx b/apps/remix-ide/src/app/providers/environment-explorer.tsx index 8f25793db9..1b612d0ac0 100644 --- a/apps/remix-ide/src/app/providers/environment-explorer.tsx +++ b/apps/remix-ide/src/app/providers/environment-explorer.tsx @@ -30,6 +30,7 @@ type ProvidersSection = `Injected` | 'Remix VMs' | 'Externals' | 'Remix forked V export class EnvironmentExplorer extends ViewPlugin { providers: { [key in ProvidersSection]: Provider[] } providersFlat: { [key: string]: Provider } + savedStates pinnedProviders: string[] dispatch: React.Dispatch = () => {} @@ -42,11 +43,27 @@ export class EnvironmentExplorer extends ViewPlugin { 'Remix forked VMs': [], 'Externals': [] } + this.savedStates = [] } async onActivation(): Promise { this.providersFlat = await this.call('blockchain', 'getAllProviders') this.pinnedProviders = await this.call('blockchain', 'getPinnedProviders') + const ssExists = await this.call('fileManager', 'exists', '.states/saved_states') + if (ssExists) { + const savedStatesDetails = await this.call('fileManager', 'readdir', '.states/saved_states') + const savedStatesFiles = Object.keys(savedStatesDetails) + if (savedStatesFiles.length) this.savedStates = [] + for (const filePath of savedStatesFiles) { + let stateDetail = await this.call('fileManager', 'readFile', filePath) + stateDetail = JSON.parse(stateDetail) + this.savedStates.push({ + name: stateDetail.stateName, + latestBlock: stateDetail.latestBlockNumber, + timestamp: stateDetail.savingTimestamp + }) + } + } else this.savedStates = [] this.renderComponent() } @@ -171,6 +188,31 @@ export class EnvironmentExplorer extends ViewPlugin {
{provider.description}
})} + {this.savedStates && this.savedStates.length > 0 && ({this.savedStates.map(state => { + return { + console.log('pinned') + } + } + > +
Latest Block: {state.latestBlock}
+
Saved at: {(new Date(state.timestamp)).toDateString()}
+
+ })} + +
) + } Date: Wed, 11 Dec 2024 18:24:34 +0530 Subject: [PATCH 10/35] list as provider --- .../app/providers/environment-explorer.tsx | 64 +++++++++---------- apps/remix-ide/src/app/udapp/run-tab.tsx | 53 ++++++++++----- apps/remix-ide/src/blockchain/blockchain.tsx | 1 + .../src/lib/components/environment.tsx | 1 + 4 files changed, 71 insertions(+), 48 deletions(-) diff --git a/apps/remix-ide/src/app/providers/environment-explorer.tsx b/apps/remix-ide/src/app/providers/environment-explorer.tsx index 1b612d0ac0..c97436b928 100644 --- a/apps/remix-ide/src/app/providers/environment-explorer.tsx +++ b/apps/remix-ide/src/app/providers/environment-explorer.tsx @@ -25,7 +25,7 @@ const profile = { methods: [] } -type ProvidersSection = `Injected` | 'Remix VMs' | 'Externals' | 'Remix forked VMs' +type ProvidersSection = `Injected` | 'Remix VMs' | 'Externals' | 'Remix forked VMs' | 'Saved VM States' export class EnvironmentExplorer extends ViewPlugin { providers: { [key in ProvidersSection]: Provider[] } @@ -40,6 +40,7 @@ export class EnvironmentExplorer extends ViewPlugin { this.providers = { 'Injected': [], 'Remix VMs': [], + 'Saved VM States': [], 'Remix forked VMs': [], 'Externals': [] } @@ -49,21 +50,6 @@ export class EnvironmentExplorer extends ViewPlugin { async onActivation(): Promise { this.providersFlat = await this.call('blockchain', 'getAllProviders') this.pinnedProviders = await this.call('blockchain', 'getPinnedProviders') - const ssExists = await this.call('fileManager', 'exists', '.states/saved_states') - if (ssExists) { - const savedStatesDetails = await this.call('fileManager', 'readdir', '.states/saved_states') - const savedStatesFiles = Object.keys(savedStatesDetails) - if (savedStatesFiles.length) this.savedStates = [] - for (const filePath of savedStatesFiles) { - let stateDetail = await this.call('fileManager', 'readFile', filePath) - stateDetail = JSON.parse(stateDetail) - this.savedStates.push({ - name: stateDetail.stateName, - latestBlock: stateDetail.latestBlockNumber, - timestamp: stateDetail.savingTimestamp - }) - } - } else this.savedStates = [] this.renderComponent() } @@ -74,6 +60,8 @@ export class EnvironmentExplorer extends ViewPlugin { this.providers['Remix forked VMs'].push(provider) } else if (provider.isVM) { this.providers['Remix VMs'].push(provider) + } else if (provider.isSavedState) { + this.providers['Saved VM States'].push(provider) } else { this.providers['Externals'].push(provider) } @@ -101,6 +89,7 @@ export class EnvironmentExplorer extends ViewPlugin { this.providers = { 'Injected': [], 'Remix VMs': [], + 'Saved VM States': [], 'Externals': [], 'Remix forked VMs': [] } @@ -188,31 +177,42 @@ export class EnvironmentExplorer extends ViewPlugin {
{provider.description}
})}
- {this.savedStates && this.savedStates.length > 0 && ({this.savedStates.map(state => { + >{this.providers['Saved VM States'].map(provider => { + const {latestBlock, timestamp} = JSON.parse(provider.description) return { - console.log('pinned') - } - } + if (pinned) { + this.emit('providerPinned', provider.name, provider) + this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) + return true + } + const providerName = await this.call('blockchain', 'getProvider') + if (providerName !== provider.name) { + this.emit('providerUnpinned', provider.name, provider) + this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) + return true + } else { + this.call('notification', 'toast', 'Cannot unpin the current selected provider') + return false + } + }} > -
Latest Block: {state.latestBlock}
-
Saved at: {(new Date(state.timestamp)).toDateString()}
+
Latest Block: {latestBlock}
+
Saved at: {(new Date(timestamp)).toDateString()}
- })} - -
) - } + })} { + const addProvider = async (position, name, displayName, isInjected, isVM, isSavedState, fork = '', dataId = '', title = '', forkedVM = false) => { await this.call('blockchain', 'addProvider', { position, options: {}, @@ -191,6 +191,7 @@ export class RunTab extends ViewPlugin { isInjected, isForkedVM: forkedVM, isVM, + isSavedState, title, init: async function () { const options = await udapp.call(name, 'init') @@ -206,13 +207,13 @@ export class RunTab extends ViewPlugin { const addCustomInjectedProvider = async (position, event, name, displayName, networkId, urls, nativeCurrency?) => { // name = `${name} through ${event.detail.info.name}` await this.engine.register([new InjectedCustomProvider(event.detail.provider, name, displayName, networkId, urls, nativeCurrency)]) - await addProvider(position, name, displayName + ' - ' + event.detail.info.name, true, false) + await addProvider(position, name, displayName + ' - ' + event.detail.info.name, true, false, false) } const registerInjectedProvider = async (event) => { const name = 'injected-' + event.detail.info.name const displayName = 'Injected Provider - ' + event.detail.info.name await this.engine.register([new InjectedProviderDefault(event.detail.provider, name)]) - await addProvider(0, name, displayName, true, false) + await addProvider(0, name, displayName, true, false, false) if (event.detail.info.name === 'MetaMask') { await addCustomInjectedProvider(7, event, 'injected-metamask-optimism', 'L2 - Optimism', '0xa', ['https://mainnet.optimism.io']) @@ -248,23 +249,43 @@ export class RunTab extends ViewPlugin { // VM const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.' - await addProvider(1, 'vm-cancun', 'Remix VM (Cancun)', false, true, 'cancun', 'settingsVMCancunMode', titleVM) - await addProvider(50, 'vm-shanghai', 'Remix VM (Shanghai)', false, true, 'shanghai', 'settingsVMShanghaiMode', titleVM) - await addProvider(51, 'vm-paris', 'Remix VM (Paris)', false, true, 'paris', 'settingsVMParisMode', titleVM) - await addProvider(52, 'vm-london', 'Remix VM (London)', false, true, 'london', 'settingsVMLondonMode', titleVM) - await addProvider(53, 'vm-berlin', 'Remix VM (Berlin)', false, true, 'berlin', 'settingsVMBerlinMode', titleVM) - await addProvider(2, 'vm-mainnet-fork', 'Remix VM - Mainnet fork', false, true, 'cancun', 'settingsVMMainnetMode', titleVM, true) - await addProvider(3, 'vm-sepolia-fork', 'Remix VM - Sepolia fork', false, true, 'cancun', 'settingsVMSepoliaMode', titleVM, true) - await addProvider(4, 'vm-custom-fork', 'Remix VM - Custom fork', false, true, '', 'settingsVMCustomMode', titleVM, true) + await addProvider(1, 'vm-cancun', 'Remix VM (Cancun)', false, true, false, 'cancun', 'settingsVMCancunMode', titleVM) + await addProvider(50, 'vm-shanghai', 'Remix VM (Shanghai)', false, true, false, 'shanghai', 'settingsVMShanghaiMode', titleVM) + await addProvider(51, 'vm-paris', 'Remix VM (Paris)', false, true, false, 'paris', 'settingsVMParisMode', titleVM) + await addProvider(52, 'vm-london', 'Remix VM (London)', false, true, false, 'london', 'settingsVMLondonMode', titleVM) + await addProvider(53, 'vm-berlin', 'Remix VM (Berlin)', false, true, false, 'berlin', 'settingsVMBerlinMode', titleVM) + await addProvider(2, 'vm-mainnet-fork', 'Remix VM - Mainnet fork', false, true, false, 'cancun', 'settingsVMMainnetMode', titleVM, true) + await addProvider(3, 'vm-sepolia-fork', 'Remix VM - Sepolia fork', false, true, false, 'cancun', 'settingsVMSepoliaMode', titleVM, true) + await addProvider(4, 'vm-custom-fork', 'Remix VM - Custom fork', false, true, false, '', 'settingsVMCustomMode', titleVM, true) + + // Saved VM States + this.on('filePanel', 'workspaceInitializationCompleted', async () => { + const ssExists = await this.call('fileManager', 'exists', '.states/saved_states') + if (ssExists) { + const savedStatesDetails = await this.call('fileManager', 'readdir', '.states/saved_states') + const savedStatesFiles = Object.keys(savedStatesDetails) + let pos = 10 + for (const filePath of savedStatesFiles) { + let stateDetail = await this.call('fileManager', 'readFile', filePath) + stateDetail = JSON.parse(stateDetail) + descriptions[stateDetail.stateName] = JSON.stringify({ + name: stateDetail.stateName, + latestBlock: stateDetail.latestBlockNumber, + timestamp: stateDetail.savingTimestamp + }) + await addProvider(pos + 1, stateDetail.stateName, stateDetail.stateName, false, false, true, stateDetail.forkName) + } + } + }) // wallet connect - await addProvider(6, 'walletconnect', 'WalletConnect', false, false) + await addProvider(6, 'walletconnect', 'WalletConnect', false, false, false) // external provider - await addProvider(10, 'basic-http-provider', 'Custom - External Http Provider', false, false) - await addProvider(20, 'hardhat-provider', 'Dev - Hardhat Provider', false, false) - await addProvider(21, 'ganache-provider', 'Dev - Ganache Provider', false, false) - await addProvider(22, 'foundry-provider', 'Dev - Foundry Provider', false, false) + await addProvider(10, 'basic-http-provider', 'Custom - External Http Provider', false, false, false) + await addProvider(20, 'hardhat-provider', 'Dev - Hardhat Provider', false, false, false) + await addProvider(21, 'ganache-provider', 'Dev - Ganache Provider', false, false, false) + await addProvider(22, 'foundry-provider', 'Dev - Foundry Provider', false, false, false) // register injected providers diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index 6ccbaed7ac..0495a34993 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -55,6 +55,7 @@ export type Provider = { description?: string isInjected: boolean isVM: boolean + isSavedState: boolean isForkedVM: boolean title: string init: () => Promise 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 de60e8bedc..816d28cc45 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -57,6 +57,7 @@ export function EnvironmentUI(props: EnvironmentProps) { let currentStateDb = await props.runTabPlugin.call('fileManager', 'readFile', `.states/${context}/state.json`) currentStateDb = JSON.parse(currentStateDb) currentStateDb.stateName = vmStateName.current + currentStateDb.forkName = currentProvider.fork currentStateDb.savingTimestamp = Date.now() await props.runTabPlugin.call('fileManager', 'writeFile', `.states/saved_states/${vmStateName.current}.json`, JSON.stringify(currentStateDb, null, 2)) props.runTabPlugin.call('notification', 'toast', `VM state ${vmStateName.current} saved.`) From 68095ec3c1c00cfa040422f15ffa52ca2c957f16 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 12 Dec 2024 19:47:34 +0530 Subject: [PATCH 11/35] saved state provider plugin --- apps/remix-ide/src/app/providers/vm-provider.tsx | 8 ++++++++ apps/remix-ide/src/app/udapp/run-tab.tsx | 12 ++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/providers/vm-provider.tsx b/apps/remix-ide/src/app/providers/vm-provider.tsx index f43386bbed..c978779b0d 100644 --- a/apps/remix-ide/src/app/providers/vm-provider.tsx +++ b/apps/remix-ide/src/app/providers/vm-provider.tsx @@ -131,3 +131,11 @@ export class CancunVMProvider extends BasicVMProvider { this.fork = 'cancun' } } + +export class SavedVMStateProvider extends BasicVMProvider { + constructor(profile, blockchain, fork) { + super(profile, blockchain) + this.blockchain = blockchain + this.fork = fork + } +} diff --git a/apps/remix-ide/src/app/udapp/run-tab.tsx b/apps/remix-ide/src/app/udapp/run-tab.tsx index 81583ddc86..1e7d8bea7f 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.tsx +++ b/apps/remix-ide/src/app/udapp/run-tab.tsx @@ -9,8 +9,7 @@ import * as packageJson from '../../../../../package.json' import { EventManager } from '@remix-project/remix-lib' import type { Blockchain } from '../../blockchain/blockchain' import type { CompilerArtefacts } from '@remix-project/core-plugin' -// import type { NetworkModule } from '../tabs/network-module' -// import type FileProvider from '../files/fileProvider' +import { SavedVMStateProvider } from '../providers/vm-provider' import { Recorder } from '../tabs/runTab/model/recorder' const _paq = (window._paq = window._paq || []) @@ -273,6 +272,15 @@ export class RunTab extends ViewPlugin { latestBlock: stateDetail.latestBlockNumber, timestamp: stateDetail.savingTimestamp }) + const svsProvider = new SavedVMStateProvider({ + name: stateDetail.stateName, + displayName: stateDetail.stateName, + kind: 'provider', + description: descriptions[stateDetail.stateName], + methods: ['sendAsync', 'init'], + version: packageJson.version + }, this.blockchain, stateDetail.forkName) + this.engine.register(svsProvider) await addProvider(pos + 1, stateDetail.stateName, stateDetail.stateName, false, false, true, stateDetail.forkName) } } From 8145f49147be454616f99616d6d8fa89f0ea088b Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 12 Dec 2024 20:45:07 +0530 Subject: [PATCH 12/35] load fresh SVSprovider --- apps/remix-ide/src/app/udapp/run-tab.tsx | 11 +- apps/remix-ide/src/blockchain/blockchain.tsx | 17 +- .../src/blockchain/execution-context.js | 2 +- .../blockchain/providers/saved-vm-state.ts | 153 ++++++++++++++++++ 4 files changed, 171 insertions(+), 12 deletions(-) create mode 100644 apps/remix-ide/src/blockchain/providers/saved-vm-state.ts diff --git a/apps/remix-ide/src/app/udapp/run-tab.tsx b/apps/remix-ide/src/app/udapp/run-tab.tsx index 1e7d8bea7f..03954bbcfe 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.tsx +++ b/apps/remix-ide/src/app/udapp/run-tab.tsx @@ -267,21 +267,22 @@ export class RunTab extends ViewPlugin { for (const filePath of savedStatesFiles) { let stateDetail = await this.call('fileManager', 'readFile', filePath) stateDetail = JSON.parse(stateDetail) - descriptions[stateDetail.stateName] = JSON.stringify({ - name: stateDetail.stateName, + const providerName = 'svs-' + stateDetail.stateName + descriptions[providerName] = JSON.stringify({ + name: providerName, latestBlock: stateDetail.latestBlockNumber, timestamp: stateDetail.savingTimestamp }) const svsProvider = new SavedVMStateProvider({ - name: stateDetail.stateName, + name: providerName, displayName: stateDetail.stateName, kind: 'provider', - description: descriptions[stateDetail.stateName], + description: descriptions[providerName], methods: ['sendAsync', 'init'], version: packageJson.version }, this.blockchain, stateDetail.forkName) this.engine.register(svsProvider) - await addProvider(pos + 1, stateDetail.stateName, stateDetail.stateName, false, false, true, stateDetail.forkName) + await addProvider(pos + 1, providerName, stateDetail.stateName, false, false, true, stateDetail.forkName) } } }) diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index 0495a34993..75c89405a1 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -7,6 +7,7 @@ import { format } from 'util' import { ExecutionContext } from './execution-context' import Config from '../config' import { VMProvider } from './providers/vm' +import { SVSProvider } from './providers/saved-vm-state' import { InjectedProvider } from './providers/injected' import { NodeProvider } from './providers/node' import { execution, EventManager, helpers } from '@remix-project/remix-lib' @@ -79,7 +80,7 @@ export class Blockchain extends Plugin { } error?: string } - providers: {[key: string]: VMProvider | InjectedProvider | NodeProvider} + providers: {[key: string]: VMProvider | InjectedProvider | NodeProvider | SVSProvider} transactionContextAPI: TransactionContextAPI registeredPluginEvents: string[] defaultPinnedProviders: string[] @@ -205,9 +206,9 @@ export class Blockchain extends Plugin { } setupProviders() { - const vmProvider = new VMProvider(this.executionContext) this.providers = {} - this.providers['vm'] = vmProvider + this.providers['vm'] = new VMProvider(this.executionContext) + this.providers['svs'] = new SVSProvider(this.executionContext) this.providers.injected = new InjectedProvider(this.executionContext) this.providers.web3 = new NodeProvider(this.executionContext, this.config) } @@ -215,6 +216,7 @@ export class Blockchain extends Plugin { getCurrentProvider() { const provider = this.getProvider() if (provider && provider.startsWith('vm')) return this.providers['vm'] + if (provider && provider.startsWith('svs')) return this.providers['svs'] if (provider && provider.startsWith('injected')) return this.providers['injected'] if (this.providers[provider]) return this.providers[provider] return this.providers.web3 // default to the common type of provider @@ -693,13 +695,16 @@ export class Blockchain extends Plugin { if (saveEvmState) { const contextExists = await this.call('fileManager', 'exists', `.states/${context}/state.json`) - if (contextExists) { const stateDb = await this.call('fileManager', 'readFile', `.states/${context}/state.json`) - await this.getCurrentProvider().resetEnvironment(stateDb) } else { - await this.getCurrentProvider().resetEnvironment() + // check if saved VM state is used as provider + const contextExists = await this.call('fileManager', 'exists', `.states/saved_states/${context.replace('svs-', '')}.json`) + if (contextExists) { + const stateDb = await this.call('fileManager', 'readFile', `.states/saved_states/${context.replace('svs-', '')}.json`) + await this.getCurrentProvider().resetEnvironment(stateDb) + } else await this.getCurrentProvider().resetEnvironment() } } else { await this.getCurrentProvider().resetEnvironment() diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index cf82b96ad8..c291c71d0b 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -58,7 +58,7 @@ export class ExecutionContext { } isVM () { - return this.executionContext.startsWith('vm') + return this.executionContext.startsWith('vm') || this.executionContext.startsWith('svs') } setWeb3 (context, web3) { diff --git a/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts b/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts new file mode 100644 index 0000000000..774c7fdca6 --- /dev/null +++ b/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts @@ -0,0 +1,153 @@ +import { Web3, FMT_BYTES, FMT_NUMBER, LegacySendAsyncProvider, LegacyRequestProvider } from 'web3' +import { fromWei, toBigInt } from 'web3-utils' +import { privateToAddress, hashPersonalMessage, isHexString, bytesToHex } from '@ethereumjs/util' +import { extend, JSONRPCRequestPayload, JSONRPCResponseCallback } from '@remix-project/remix-simulator' +import { ExecutionContext } from '../execution-context' + +export class SVSProvider { + executionContext: ExecutionContext + web3: Web3 + worker: Worker + provider: { + sendAsync: (query: JSONRPCRequestPayload, callback: JSONRPCResponseCallback) => void + request: (query: JSONRPCRequestPayload) => Promise + } + newAccountCallback: {[stamp: number]: (error: Error, address: string) => void} + constructor (executionContext: ExecutionContext) { + this.executionContext = executionContext + this.worker = null + this.provider = null + this.newAccountCallback = {} + } + + getAccounts (cb) { + this.web3.eth.getAccounts() + .then(accounts => cb(null, accounts)) + .catch(err => { + cb('No accounts?') + }) + } + + async resetEnvironment (stringifiedState?: string) { + if (this.worker) this.worker.terminate() + this.worker = new Worker(new URL('./worker-vm', import.meta.url)) + const provider = this.executionContext.getProviderObject() + + let incr = 0 + const stamps = {} + + return new Promise((resolve, reject) => { + this.worker.addEventListener('message', (msg) => { + if (msg.data.cmd === 'requestResult' && stamps[msg.data.stamp]) { + if (msg.data.error) { + stamps[msg.data.stamp].reject(msg.data.error) + } else { + stamps[msg.data.stamp].resolve(msg.data.result) + } + } else if (msg.data.cmd === 'sendAsyncResult' && stamps[msg.data.stamp]) { + if (stamps[msg.data.stamp].callback) { + stamps[msg.data.stamp].callback(msg.data.error, msg.data.result) + return + } + if (msg.data.error) { + stamps[msg.data.stamp].reject(msg.data.error) + } else { + stamps[msg.data.stamp].resolve(msg.data.result) + } + } else if (msg.data.cmd === 'initiateResult') { + if (!msg.data.error) { + this.provider = { + sendAsync: (query, callback) => { + return new Promise((resolve, reject) => { + const stamp = Date.now() + incr + incr++ + stamps[stamp] = { callback, resolve, reject } + this.worker.postMessage({ cmd: 'sendAsync', query, stamp }) + }) + }, + request: (query) => { + return new Promise((resolve, reject) => { + const stamp = Date.now() + incr + incr++ + stamps[stamp] = { resolve, reject } + this.worker.postMessage({ cmd: 'request', query, stamp }) + }) + } + } + this.web3 = new Web3(this.provider as (LegacySendAsyncProvider | LegacyRequestProvider)) + this.web3.setConfig({ defaultTransactionType: '0x0' }) + extend(this.web3) + this.executionContext.setWeb3(this.executionContext.getProvider(), this.web3) + resolve({}) + } else { + reject(new Error(msg.data.error)) + } + } else if (msg.data.cmd === 'newAccountResult') { + if (this.newAccountCallback[msg.data.stamp]) { + this.newAccountCallback[msg.data.stamp](msg.data.error, msg.data.result) + delete this.newAccountCallback[msg.data.stamp] + } + } + }) + if (stringifiedState) { + try { + const blockchainState = JSON.parse(stringifiedState) + const blockNumber = parseInt(blockchainState.latestBlockNumber, 16) + console.log('blockNumber-in resetEnvironment-->', blockNumber) + const stateDb = blockchainState.db + + this.worker.postMessage({ + cmd: 'init', + fork: this.executionContext.getCurrentFork(), + nodeUrl: provider?.options['nodeUrl'], + blockNumber, + stateDb, + blocks: blockchainState.blocks + }) + } catch (e) { + console.error(e) + } + } else { + this.worker.postMessage({ + cmd: 'init', + fork: this.executionContext.getCurrentFork(), + nodeUrl: provider?.options['nodeUrl'], + blockNumber: provider?.options['blockNumber'] + }) + } + }) + } + + // TODO: is still here because of the plugin API + // can be removed later when we update the API + createVMAccount (newAccount) { + const { privateKey, balance } = newAccount + this.worker.postMessage({ cmd: 'addAccount', privateKey: privateKey, balance }) + const privKey = Buffer.from(privateKey, 'hex') + return bytesToHex(privateToAddress(privKey)) + } + + newAccount (_passwordPromptCb, cb) { + const stamp = Date.now() + this.newAccountCallback[stamp] = cb + this.worker.postMessage({ cmd: 'newAccount', stamp }) + } + + async getBalanceInEther (address) { + const balance = await this.web3.eth.getBalance(address, undefined, { number: FMT_NUMBER.HEX, bytes: FMT_BYTES.HEX }) + const balInString = toBigInt(balance).toString(10) + return balInString === '0' ? balInString : fromWei(balInString, 'ether') + } + + getGasPrice (cb) { + this.web3.eth.getGasPrice().then((result => cb(null, result))).catch((error) => cb(error)) + } + + signMessage (message, account, _passphrase, cb) { + const messageHash = hashPersonalMessage(Buffer.from(message)) + message = isHexString(message) ? message : Web3.utils.utf8ToHex(message) + this.web3.eth.sign(message, account) + .then(signedData => cb(null, bytesToHex(messageHash), signedData)) + .catch(error => cb(error)) + } +} From 42ad8fad3946f8d23c94e65f9bbd8e32a321dfcd Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 12 Dec 2024 21:56:12 +0530 Subject: [PATCH 13/35] fix linting --- libs/remix-ui/run-tab/src/lib/components/environment.tsx | 6 +++--- libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) 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 816d28cc45..785a5e3c7e 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -31,8 +31,8 @@ export function EnvironmentUI(props: EnvironmentProps) { return (
+ + { currentProvider && currentProvider.isVM && isSaveEvmStateChecked && }> - + }
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 b3d9b28087..733c867205 100644 --- a/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx @@ -12,12 +12,12 @@ export function SettingsUI(props: SettingsProps) { return (
- From aa3e1d9fa315261897dd32bf3cbb3a549f3cf4df Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 16 Dec 2024 15:52:27 +0530 Subject: [PATCH 14/35] save and load state --- apps/remix-ide/src/blockchain/blockchain.tsx | 20 ++++++++++++++++--- .../blockchain/providers/saved-vm-state.ts | 1 - 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index 75c89405a1..c98f9c6351 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -958,8 +958,23 @@ export class Blockchain extends Plugin { if (isVM) { if (!tx.useCall && this.config.get('settings/save-evm-state')) { try { - const state = await this.executionContext.getStateDetails() - this.call('fileManager', 'writeFile', `.states/${this.executionContext.getProvider()}/state.json`, state) + let state = await this.executionContext.getStateDetails() + const provider = this.executionContext.getProvider() + if (provider.startsWith('svs')) { + const stateName = provider.replace('svs-', '') + const stateFileExists = this.call('fileManager', 'exists', `.states/saved_states/${stateName}.json`) + if (stateFileExists) { + let stateDetails = await this.call('fileManager', 'readFile', `.states/saved_states/${stateName}.json`) + stateDetails = JSON.parse(stateDetails) + state = JSON.parse(state) + state['stateName'] = stateDetails.stateName + state['forkName'] = stateDetails.forkName + state['savingTimestamp'] = stateDetails.savingTimestamp + state = JSON.stringify(state, null, 2) + } + this.call('fileManager', 'writeFile', `.states/saved_states/${stateName}.json`, state) + } + else this.call('fileManager', 'writeFile', `.states/${provider}/state.json`, state) } catch (e) { console.error(e) } @@ -991,7 +1006,6 @@ export class Blockchain extends Plugin { this.call('terminal', 'logHtml', finalLogs) } execResult = await this.web3().remix.getExecutionResultFromSimulator(txResult.transactionHash) - if (execResult) { // if it's not the VM, we don't have return value. We only have the transaction, and it does not contain the return value. returnValue = execResult diff --git a/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts b/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts index 774c7fdca6..b23c2d93ca 100644 --- a/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts +++ b/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts @@ -93,7 +93,6 @@ export class SVSProvider { try { const blockchainState = JSON.parse(stringifiedState) const blockNumber = parseInt(blockchainState.latestBlockNumber, 16) - console.log('blockNumber-in resetEnvironment-->', blockNumber) const stateDb = blockchainState.db this.worker.postMessage({ From 28f4e03705b203241d37db9b6d8f8169382a5920 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 16 Dec 2024 16:27:30 +0530 Subject: [PATCH 15/35] fix provider loading --- apps/remix-ide/src/blockchain/blockchain.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index c98f9c6351..e034d18858 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -590,10 +590,8 @@ export class Blockchain extends Plugin { } web3() { - const isVM = this.executionContext.isVM() - if (isVM) { - return (this.providers.vm as VMProvider).web3 - } + if (this.executionContext.executionContext.startsWith('vm-')) return (this.providers.vm as VMProvider).web3 + else if (this.executionContext.executionContext.startsWith('svs-')) return (this.providers.svs as SVSProvider).web3 return this.executionContext.web3() } From a86296d8d1471bee592f6a1a05bb8f832f0ae0c9 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 16 Dec 2024 16:38:31 +0530 Subject: [PATCH 16/35] fix linting --- .../app/providers/environment-explorer.tsx | 2 +- apps/remix-ide/src/app/udapp/run-tab.tsx | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/remix-ide/src/app/providers/environment-explorer.tsx b/apps/remix-ide/src/app/providers/environment-explorer.tsx index c97436b928..1765aaf938 100644 --- a/apps/remix-ide/src/app/providers/environment-explorer.tsx +++ b/apps/remix-ide/src/app/providers/environment-explorer.tsx @@ -182,7 +182,7 @@ export class EnvironmentExplorer extends ViewPlugin { title='Deploy to an In-browser Saved VM State.' hScrollable={false} >{this.providers['Saved VM States'].map(provider => { - const {latestBlock, timestamp} = JSON.parse(provider.description) + const { latestBlock, timestamp } = JSON.parse(provider.description) return Date: Mon, 16 Dec 2024 17:23:29 +0530 Subject: [PATCH 17/35] improve svs details --- .../src/app/providers/environment-explorer.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide/src/app/providers/environment-explorer.tsx b/apps/remix-ide/src/app/providers/environment-explorer.tsx index 1765aaf938..facc93e4d8 100644 --- a/apps/remix-ide/src/app/providers/environment-explorer.tsx +++ b/apps/remix-ide/src/app/providers/environment-explorer.tsx @@ -1,6 +1,6 @@ import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' -import { PluginViewWrapper } from '@remix-ui/helper' +import { CustomTooltip, PluginViewWrapper } from '@remix-ui/helper' import { RemixUIGridView } from '@remix-ui/remix-ui-grid-view' import { RemixUIGridSection } from '@remix-ui/remix-ui-grid-section' import { RemixUIGridCell } from '@remix-ui/remix-ui-grid-cell' @@ -30,7 +30,6 @@ type ProvidersSection = `Injected` | 'Remix VMs' | 'Externals' | 'Remix forked V export class EnvironmentExplorer extends ViewPlugin { providers: { [key in ProvidersSection]: Provider[] } providersFlat: { [key: string]: Provider } - savedStates pinnedProviders: string[] dispatch: React.Dispatch = () => {} @@ -44,7 +43,6 @@ export class EnvironmentExplorer extends ViewPlugin { 'Remix forked VMs': [], 'Externals': [] } - this.savedStates = [] } async onActivation(): Promise { @@ -209,8 +207,14 @@ export class EnvironmentExplorer extends ViewPlugin { } }} > -
Latest Block: {latestBlock}
-
Saved at: {(new Date(timestamp)).toDateString()}
+
Latest Block: {parseInt(latestBlock)}
+ +
Saved at: {(new Date(timestamp)).toDateString()}
+
})} Date: Mon, 16 Dec 2024 18:03:53 +0530 Subject: [PATCH 18/35] extend vmp --- .../blockchain/providers/saved-vm-state.ts | 153 +----------------- 1 file changed, 2 insertions(+), 151 deletions(-) diff --git a/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts b/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts index b23c2d93ca..08be7e78a0 100644 --- a/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts +++ b/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts @@ -1,152 +1,3 @@ -import { Web3, FMT_BYTES, FMT_NUMBER, LegacySendAsyncProvider, LegacyRequestProvider } from 'web3' -import { fromWei, toBigInt } from 'web3-utils' -import { privateToAddress, hashPersonalMessage, isHexString, bytesToHex } from '@ethereumjs/util' -import { extend, JSONRPCRequestPayload, JSONRPCResponseCallback } from '@remix-project/remix-simulator' -import { ExecutionContext } from '../execution-context' +import { VMProvider } from './vm' -export class SVSProvider { - executionContext: ExecutionContext - web3: Web3 - worker: Worker - provider: { - sendAsync: (query: JSONRPCRequestPayload, callback: JSONRPCResponseCallback) => void - request: (query: JSONRPCRequestPayload) => Promise - } - newAccountCallback: {[stamp: number]: (error: Error, address: string) => void} - constructor (executionContext: ExecutionContext) { - this.executionContext = executionContext - this.worker = null - this.provider = null - this.newAccountCallback = {} - } - - getAccounts (cb) { - this.web3.eth.getAccounts() - .then(accounts => cb(null, accounts)) - .catch(err => { - cb('No accounts?') - }) - } - - async resetEnvironment (stringifiedState?: string) { - if (this.worker) this.worker.terminate() - this.worker = new Worker(new URL('./worker-vm', import.meta.url)) - const provider = this.executionContext.getProviderObject() - - let incr = 0 - const stamps = {} - - return new Promise((resolve, reject) => { - this.worker.addEventListener('message', (msg) => { - if (msg.data.cmd === 'requestResult' && stamps[msg.data.stamp]) { - if (msg.data.error) { - stamps[msg.data.stamp].reject(msg.data.error) - } else { - stamps[msg.data.stamp].resolve(msg.data.result) - } - } else if (msg.data.cmd === 'sendAsyncResult' && stamps[msg.data.stamp]) { - if (stamps[msg.data.stamp].callback) { - stamps[msg.data.stamp].callback(msg.data.error, msg.data.result) - return - } - if (msg.data.error) { - stamps[msg.data.stamp].reject(msg.data.error) - } else { - stamps[msg.data.stamp].resolve(msg.data.result) - } - } else if (msg.data.cmd === 'initiateResult') { - if (!msg.data.error) { - this.provider = { - sendAsync: (query, callback) => { - return new Promise((resolve, reject) => { - const stamp = Date.now() + incr - incr++ - stamps[stamp] = { callback, resolve, reject } - this.worker.postMessage({ cmd: 'sendAsync', query, stamp }) - }) - }, - request: (query) => { - return new Promise((resolve, reject) => { - const stamp = Date.now() + incr - incr++ - stamps[stamp] = { resolve, reject } - this.worker.postMessage({ cmd: 'request', query, stamp }) - }) - } - } - this.web3 = new Web3(this.provider as (LegacySendAsyncProvider | LegacyRequestProvider)) - this.web3.setConfig({ defaultTransactionType: '0x0' }) - extend(this.web3) - this.executionContext.setWeb3(this.executionContext.getProvider(), this.web3) - resolve({}) - } else { - reject(new Error(msg.data.error)) - } - } else if (msg.data.cmd === 'newAccountResult') { - if (this.newAccountCallback[msg.data.stamp]) { - this.newAccountCallback[msg.data.stamp](msg.data.error, msg.data.result) - delete this.newAccountCallback[msg.data.stamp] - } - } - }) - if (stringifiedState) { - try { - const blockchainState = JSON.parse(stringifiedState) - const blockNumber = parseInt(blockchainState.latestBlockNumber, 16) - const stateDb = blockchainState.db - - this.worker.postMessage({ - cmd: 'init', - fork: this.executionContext.getCurrentFork(), - nodeUrl: provider?.options['nodeUrl'], - blockNumber, - stateDb, - blocks: blockchainState.blocks - }) - } catch (e) { - console.error(e) - } - } else { - this.worker.postMessage({ - cmd: 'init', - fork: this.executionContext.getCurrentFork(), - nodeUrl: provider?.options['nodeUrl'], - blockNumber: provider?.options['blockNumber'] - }) - } - }) - } - - // TODO: is still here because of the plugin API - // can be removed later when we update the API - createVMAccount (newAccount) { - const { privateKey, balance } = newAccount - this.worker.postMessage({ cmd: 'addAccount', privateKey: privateKey, balance }) - const privKey = Buffer.from(privateKey, 'hex') - return bytesToHex(privateToAddress(privKey)) - } - - newAccount (_passwordPromptCb, cb) { - const stamp = Date.now() - this.newAccountCallback[stamp] = cb - this.worker.postMessage({ cmd: 'newAccount', stamp }) - } - - async getBalanceInEther (address) { - const balance = await this.web3.eth.getBalance(address, undefined, { number: FMT_NUMBER.HEX, bytes: FMT_BYTES.HEX }) - const balInString = toBigInt(balance).toString(10) - return balInString === '0' ? balInString : fromWei(balInString, 'ether') - } - - getGasPrice (cb) { - this.web3.eth.getGasPrice().then((result => cb(null, result))).catch((error) => cb(error)) - } - - signMessage (message, account, _passphrase, cb) { - const messageHash = hashPersonalMessage(Buffer.from(message)) - message = isHexString(message) ? message : Web3.utils.utf8ToHex(message) - this.web3.eth.sign(message, account) - .then(signedData => cb(null, bytesToHex(messageHash), signedData)) - .catch(error => cb(error)) - } -} +export class SVSProvider extends VMProvider {} From d83dd0a95b8f6cd199110c89c54c5c3e79b4d565 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 16 Dec 2024 18:54:05 +0530 Subject: [PATCH 19/35] add provider on saved state --- apps/remix-ide/src/app/udapp/run-tab.tsx | 27 ++++++++++++------- .../src/lib/components/environment.tsx | 1 + 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/apps/remix-ide/src/app/udapp/run-tab.tsx b/apps/remix-ide/src/app/udapp/run-tab.tsx index d2d557ab33..564d100a94 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.tsx +++ b/apps/remix-ide/src/app/udapp/run-tab.tsx @@ -258,14 +258,8 @@ export class RunTab extends ViewPlugin { await addProvider(4, 'vm-custom-fork', 'Remix VM - Custom fork', false, true, false, '', 'settingsVMCustomMode', titleVM, true) // Saved VM States - this.on('filePanel', 'workspaceInitializationCompleted', async () => { - const ssExists = await this.call('fileManager', 'exists', '.states/saved_states') - if (ssExists) { - const savedStatesDetails = await this.call('fileManager', 'readdir', '.states/saved_states') - const savedStatesFiles = Object.keys(savedStatesDetails) - const pos = 10 - for (const filePath of savedStatesFiles) { - let stateDetail = await this.call('fileManager', 'readFile', filePath) + const addSVSProvider = async(stateFilePath, pos) => { + let stateDetail = await this.call('fileManager', 'readFile', stateFilePath) stateDetail = JSON.parse(stateDetail) const providerName = 'svs-' + stateDetail.stateName descriptions[providerName] = JSON.stringify({ @@ -282,11 +276,26 @@ export class RunTab extends ViewPlugin { version: packageJson.version }, this.blockchain, stateDetail.forkName) this.engine.register(svsProvider) - await addProvider(pos + 1, providerName, stateDetail.stateName, false, false, true, stateDetail.forkName) + await addProvider(pos, providerName, stateDetail.stateName, false, false, true, stateDetail.forkName) + } + + this.on('filePanel', 'workspaceInitializationCompleted', async () => { + const ssExists = await this.call('fileManager', 'exists', '.states/saved_states') + if (ssExists) { + const savedStatesDetails = await this.call('fileManager', 'readdir', '.states/saved_states') + const savedStatesFiles = Object.keys(savedStatesDetails) + let pos = 10 + for (const filePath of savedStatesFiles) { + pos += 1 + await addSVSProvider(filePath, pos) } } }) + this.on('udapp', 'vmStateSaved', async (stateName) => { + await addSVSProvider(`.states/saved_states/${stateName}.json`, 20) + }) + // wallet connect await addProvider(6, 'walletconnect', 'WalletConnect', false, false, false) 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 785a5e3c7e..aad3b65c01 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -60,6 +60,7 @@ export function EnvironmentUI(props: EnvironmentProps) { currentStateDb.forkName = currentProvider.fork currentStateDb.savingTimestamp = Date.now() await props.runTabPlugin.call('fileManager', 'writeFile', `.states/saved_states/${vmStateName.current}.json`, JSON.stringify(currentStateDb, null, 2)) + props.runTabPlugin.emit('vmStateSaved', vmStateName.current) props.runTabPlugin.call('notification', 'toast', `VM state ${vmStateName.current} saved.`) } }, From 33df65b5daa765650e6f96f19681b67293b9f243 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 16 Dec 2024 19:11:57 +0530 Subject: [PATCH 20/35] remove SVSprovider --- apps/remix-ide/src/app/udapp/run-tab.tsx | 1 + apps/remix-ide/src/blockchain/blockchain.tsx | 7 +++---- apps/remix-ide/src/blockchain/providers/saved-vm-state.ts | 3 --- 3 files changed, 4 insertions(+), 7 deletions(-) delete mode 100644 apps/remix-ide/src/blockchain/providers/saved-vm-state.ts diff --git a/apps/remix-ide/src/app/udapp/run-tab.tsx b/apps/remix-ide/src/app/udapp/run-tab.tsx index 564d100a94..066825cbbd 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.tsx +++ b/apps/remix-ide/src/app/udapp/run-tab.tsx @@ -267,6 +267,7 @@ export class RunTab extends ViewPlugin { latestBlock: stateDetail.latestBlockNumber, timestamp: stateDetail.savingTimestamp }) + // Create and register provider plugin for saved states const svsProvider = new SavedVMStateProvider({ name: providerName, displayName: stateDetail.stateName, diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index e034d18858..9a8eca72d4 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -7,7 +7,6 @@ import { format } from 'util' import { ExecutionContext } from './execution-context' import Config from '../config' import { VMProvider } from './providers/vm' -import { SVSProvider } from './providers/saved-vm-state' import { InjectedProvider } from './providers/injected' import { NodeProvider } from './providers/node' import { execution, EventManager, helpers } from '@remix-project/remix-lib' @@ -80,7 +79,7 @@ export class Blockchain extends Plugin { } error?: string } - providers: {[key: string]: VMProvider | InjectedProvider | NodeProvider | SVSProvider} + providers: {[key: string]: VMProvider | InjectedProvider | NodeProvider } transactionContextAPI: TransactionContextAPI registeredPluginEvents: string[] defaultPinnedProviders: string[] @@ -208,7 +207,7 @@ export class Blockchain extends Plugin { setupProviders() { this.providers = {} this.providers['vm'] = new VMProvider(this.executionContext) - this.providers['svs'] = new SVSProvider(this.executionContext) + this.providers['svs'] = new VMProvider(this.executionContext) this.providers.injected = new InjectedProvider(this.executionContext) this.providers.web3 = new NodeProvider(this.executionContext, this.config) } @@ -591,7 +590,7 @@ export class Blockchain extends Plugin { web3() { if (this.executionContext.executionContext.startsWith('vm-')) return (this.providers.vm as VMProvider).web3 - else if (this.executionContext.executionContext.startsWith('svs-')) return (this.providers.svs as SVSProvider).web3 + else if (this.executionContext.executionContext.startsWith('svs-')) return (this.providers.svs as VMProvider).web3 return this.executionContext.web3() } diff --git a/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts b/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts deleted file mode 100644 index 08be7e78a0..0000000000 --- a/apps/remix-ide/src/blockchain/providers/saved-vm-state.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { VMProvider } from './vm' - -export class SVSProvider extends VMProvider {} From cbeb4ef158e4ad02c04636c153b0363b0707da9b Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 17 Dec 2024 13:13:02 +0530 Subject: [PATCH 21/35] remove SVS plugins from PM list --- apps/remix-ide/src/remixAppManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index c514350909..40d64f8812 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -110,7 +110,7 @@ const isInjectedProvider = (name) => { } const isVM = (name) => { - return name.startsWith('vm') + return name.startsWith('vm') || name.startsWith('svs') } const isScriptRunner = (name) => { From 973105b85d4e334535b6ffe501013f49204a525d Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 17 Dec 2024 13:30:51 +0530 Subject: [PATCH 22/35] refactoring --- apps/remix-ide/src/app/udapp/run-tab.tsx | 2 +- apps/remix-ide/src/blockchain/blockchain.tsx | 15 ++++++++------- .../remix-ide/src/blockchain/execution-context.js | 2 +- apps/remix-ide/src/remixAppManager.js | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/remix-ide/src/app/udapp/run-tab.tsx b/apps/remix-ide/src/app/udapp/run-tab.tsx index 066825cbbd..a4c315debe 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.tsx +++ b/apps/remix-ide/src/app/udapp/run-tab.tsx @@ -261,7 +261,7 @@ export class RunTab extends ViewPlugin { const addSVSProvider = async(stateFilePath, pos) => { let stateDetail = await this.call('fileManager', 'readFile', stateFilePath) stateDetail = JSON.parse(stateDetail) - const providerName = 'svs-' + stateDetail.stateName + const providerName = 'vm-svs-' + stateDetail.stateName descriptions[providerName] = JSON.stringify({ name: providerName, latestBlock: stateDetail.latestBlockNumber, diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index 9a8eca72d4..f0822370e2 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -207,7 +207,7 @@ export class Blockchain extends Plugin { setupProviders() { this.providers = {} this.providers['vm'] = new VMProvider(this.executionContext) - this.providers['svs'] = new VMProvider(this.executionContext) + this.providers['vm-svs'] = new VMProvider(this.executionContext) this.providers.injected = new InjectedProvider(this.executionContext) this.providers.web3 = new NodeProvider(this.executionContext, this.config) } @@ -215,7 +215,7 @@ export class Blockchain extends Plugin { getCurrentProvider() { const provider = this.getProvider() if (provider && provider.startsWith('vm')) return this.providers['vm'] - if (provider && provider.startsWith('svs')) return this.providers['svs'] + if (provider && provider.startsWith('vm-svs')) return this.providers['vm-svs'] if (provider && provider.startsWith('injected')) return this.providers['injected'] if (this.providers[provider]) return this.providers[provider] return this.providers.web3 // default to the common type of provider @@ -590,7 +590,7 @@ export class Blockchain extends Plugin { web3() { if (this.executionContext.executionContext.startsWith('vm-')) return (this.providers.vm as VMProvider).web3 - else if (this.executionContext.executionContext.startsWith('svs-')) return (this.providers.svs as VMProvider).web3 + else if (this.executionContext.executionContext.startsWith('vm-svs-')) return (this.providers['vm-svs'] as VMProvider).web3 return this.executionContext.web3() } @@ -697,9 +697,10 @@ export class Blockchain extends Plugin { await this.getCurrentProvider().resetEnvironment(stateDb) } else { // check if saved VM state is used as provider - const contextExists = await this.call('fileManager', 'exists', `.states/saved_states/${context.replace('svs-', '')}.json`) + const stateName = context.replace('vm-svs-', '') + const contextExists = await this.call('fileManager', 'exists', `.states/saved_states/${stateName}.json`) if (contextExists) { - const stateDb = await this.call('fileManager', 'readFile', `.states/saved_states/${context.replace('svs-', '')}.json`) + const stateDb = await this.call('fileManager', 'readFile', `.states/saved_states/${stateName}.json`) await this.getCurrentProvider().resetEnvironment(stateDb) } else await this.getCurrentProvider().resetEnvironment() } @@ -957,8 +958,8 @@ export class Blockchain extends Plugin { try { let state = await this.executionContext.getStateDetails() const provider = this.executionContext.getProvider() - if (provider.startsWith('svs')) { - const stateName = provider.replace('svs-', '') + if (provider.startsWith('vm-svs-')) { + const stateName = provider.replace('vm-svs-', '') const stateFileExists = this.call('fileManager', 'exists', `.states/saved_states/${stateName}.json`) if (stateFileExists) { let stateDetails = await this.call('fileManager', 'readFile', `.states/saved_states/${stateName}.json`) diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index c291c71d0b..cf82b96ad8 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -58,7 +58,7 @@ export class ExecutionContext { } isVM () { - return this.executionContext.startsWith('vm') || this.executionContext.startsWith('svs') + return this.executionContext.startsWith('vm') } setWeb3 (context, web3) { diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 40d64f8812..c514350909 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -110,7 +110,7 @@ const isInjectedProvider = (name) => { } const isVM = (name) => { - return name.startsWith('vm') || name.startsWith('svs') + return name.startsWith('vm') } const isScriptRunner = (name) => { From 519e825dd6c59dc871cdc8f7d7c663a4f73af1b5 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 17 Dec 2024 13:46:16 +0530 Subject: [PATCH 23/35] more refactor --- apps/remix-ide/src/blockchain/blockchain.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index f0822370e2..d5832e9ff4 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -207,7 +207,6 @@ export class Blockchain extends Plugin { setupProviders() { this.providers = {} this.providers['vm'] = new VMProvider(this.executionContext) - this.providers['vm-svs'] = new VMProvider(this.executionContext) this.providers.injected = new InjectedProvider(this.executionContext) this.providers.web3 = new NodeProvider(this.executionContext, this.config) } @@ -215,7 +214,6 @@ export class Blockchain extends Plugin { getCurrentProvider() { const provider = this.getProvider() if (provider && provider.startsWith('vm')) return this.providers['vm'] - if (provider && provider.startsWith('vm-svs')) return this.providers['vm-svs'] if (provider && provider.startsWith('injected')) return this.providers['injected'] if (this.providers[provider]) return this.providers[provider] return this.providers.web3 // default to the common type of provider @@ -589,8 +587,10 @@ export class Blockchain extends Plugin { } web3() { - if (this.executionContext.executionContext.startsWith('vm-')) return (this.providers.vm as VMProvider).web3 - else if (this.executionContext.executionContext.startsWith('vm-svs-')) return (this.providers['vm-svs'] as VMProvider).web3 + const isVM = this.executionContext.isVM() + if (isVM) { + return (this.providers.vm as VMProvider).web3 + } return this.executionContext.web3() } From 3c844b531cd85fa81bd177a203fc6df78c8e2318 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 17 Dec 2024 14:03:37 +0530 Subject: [PATCH 24/35] add tip --- apps/remix-dapp/src/locales/en/udapp.json | 1 + apps/remix-ide/src/app/tabs/locales/en/udapp.json | 1 + libs/remix-ui/run-tab/src/lib/components/environment.tsx | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/apps/remix-dapp/src/locales/en/udapp.json b/apps/remix-dapp/src/locales/en/udapp.json index 431eb59ed4..26fd59aa95 100644 --- a/apps/remix-dapp/src/locales/en/udapp.json +++ b/apps/remix-dapp/src/locales/en/udapp.json @@ -51,6 +51,7 @@ "udapp.signature": "signature", "udapp.saveVmStateTitle": "Save VM state", "udapp.saveVmStateLabel": "State Name", + "udapp.saveVmStateTip": "Saved VM states can be pinned as environment using Environment Explorer", "udapp.injectedTitle": "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type).", "udapp.createNewAccount": "Create a new account", "udapp.web3Title": "Creating an account is possible only in Personal mode. Please go to Settings to enable it.", diff --git a/apps/remix-ide/src/app/tabs/locales/en/udapp.json b/apps/remix-ide/src/app/tabs/locales/en/udapp.json index f9c88dc1e6..f54334db1e 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/udapp.json +++ b/apps/remix-ide/src/app/tabs/locales/en/udapp.json @@ -51,6 +51,7 @@ "udapp.signature": "signature", "udapp.saveVmStateTitle": "Save VM state", "udapp.saveVmStateLabel": "State Name", + "udapp.saveVmStateTip": "Saved VM states can be pinned as environment using Environment Explorer", "udapp.injectedTitle": "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type).", "udapp.createNewAccount": "Create new account", "udapp.web3Title": "Creating an account is possible only in Personal mode. Please go to Settings to enable it.", 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 aad3b65c01..192bcaac6a 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -40,6 +40,10 @@ export function EnvironmentUI(props: EnvironmentProps) { className="form-control" onChange={(e) => vmStateName.current = e.target.value} /> +
+
+ Tip: +
) } From 0127280b00d307a24cd1e259307b40ea94c6bc05 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 17 Dec 2024 15:53:31 +0530 Subject: [PATCH 25/35] fix linting --- apps/remix-ide/src/app/udapp/run-tab.tsx | 36 ++++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/apps/remix-ide/src/app/udapp/run-tab.tsx b/apps/remix-ide/src/app/udapp/run-tab.tsx index a4c315debe..50493830bd 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.tsx +++ b/apps/remix-ide/src/app/udapp/run-tab.tsx @@ -260,24 +260,24 @@ export class RunTab extends ViewPlugin { // Saved VM States const addSVSProvider = async(stateFilePath, pos) => { let stateDetail = await this.call('fileManager', 'readFile', stateFilePath) - stateDetail = JSON.parse(stateDetail) - const providerName = 'vm-svs-' + stateDetail.stateName - descriptions[providerName] = JSON.stringify({ - name: providerName, - latestBlock: stateDetail.latestBlockNumber, - timestamp: stateDetail.savingTimestamp - }) - // Create and register provider plugin for saved states - const svsProvider = new SavedVMStateProvider({ - name: providerName, - displayName: stateDetail.stateName, - kind: 'provider', - description: descriptions[providerName], - methods: ['sendAsync', 'init'], - version: packageJson.version - }, this.blockchain, stateDetail.forkName) - this.engine.register(svsProvider) - await addProvider(pos, providerName, stateDetail.stateName, false, false, true, stateDetail.forkName) + stateDetail = JSON.parse(stateDetail) + const providerName = 'vm-svs-' + stateDetail.stateName + descriptions[providerName] = JSON.stringify({ + name: providerName, + latestBlock: stateDetail.latestBlockNumber, + timestamp: stateDetail.savingTimestamp + }) + // Create and register provider plugin for saved states + const svsProvider = new SavedVMStateProvider({ + name: providerName, + displayName: stateDetail.stateName, + kind: 'provider', + description: descriptions[providerName], + methods: ['sendAsync', 'init'], + version: packageJson.version + }, this.blockchain, stateDetail.forkName) + this.engine.register(svsProvider) + await addProvider(pos, providerName, stateDetail.stateName, false, false, true, stateDetail.forkName) } this.on('filePanel', 'workspaceInitializationCompleted', async () => { From 0d5a23f98d4567b7a1c30d05c689734bce6885e5 Mon Sep 17 00:00:00 2001 From: rebustron Date: Tue, 17 Dec 2024 09:57:27 +0100 Subject: [PATCH 26/35] fixed broken link constant.ts --- apps/circuit-compiler/src/app/actions/constant.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/circuit-compiler/src/app/actions/constant.ts b/apps/circuit-compiler/src/app/actions/constant.ts index 6dc9ffcff0..4b3dc07e0e 100644 --- a/apps/circuit-compiler/src/app/actions/constant.ts +++ b/apps/circuit-compiler/src/app/actions/constant.ts @@ -318,7 +318,7 @@ contract PlonkVerifier { /////// // Computes the inverse of an array of values - // See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations + // See https://vitalik.eth.limo/general/2018/07/21/starks_part_3.html in section where explain fields operations ////// function inverseArray(pVals, n) { From 796b4eaaa8096a77cb376874a4aa0384ad55f797 Mon Sep 17 00:00:00 2001 From: rebustron Date: Tue, 17 Dec 2024 09:58:39 +0100 Subject: [PATCH 27/35] fixed broken link plonk_verifier.sol.ejs --- .../src/templates/rln/templates/plonk_verifier.sol.ejs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ws-templates/src/templates/rln/templates/plonk_verifier.sol.ejs b/libs/remix-ws-templates/src/templates/rln/templates/plonk_verifier.sol.ejs index 8b3ed1d109..963bade7f1 100644 --- a/libs/remix-ws-templates/src/templates/rln/templates/plonk_verifier.sol.ejs +++ b/libs/remix-ws-templates/src/templates/rln/templates/plonk_verifier.sol.ejs @@ -152,7 +152,7 @@ contract PlonkVerifier { /////// // Computes the inverse of an array of values - // See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations + // See https://vitalik.eth.limo/general/2018/07/21/starks_part_3.html in section where explain fields operations ////// function inverseArray(pVals, n) { @@ -707,4 +707,4 @@ contract PlonkVerifier { } } -} \ No newline at end of file +} From d9e244b3cb57e149d9c9323b9712bfd392031b9b Mon Sep 17 00:00:00 2001 From: rebustron Date: Tue, 17 Dec 2024 09:59:27 +0100 Subject: [PATCH 28/35] fixed broken link plonk_verifier.sol.ejs --- .../src/templates/semaphore/templates/plonk_verifier.sol.ejs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ws-templates/src/templates/semaphore/templates/plonk_verifier.sol.ejs b/libs/remix-ws-templates/src/templates/semaphore/templates/plonk_verifier.sol.ejs index 8b3ed1d109..963bade7f1 100644 --- a/libs/remix-ws-templates/src/templates/semaphore/templates/plonk_verifier.sol.ejs +++ b/libs/remix-ws-templates/src/templates/semaphore/templates/plonk_verifier.sol.ejs @@ -152,7 +152,7 @@ contract PlonkVerifier { /////// // Computes the inverse of an array of values - // See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations + // See https://vitalik.eth.limo/general/2018/07/21/starks_part_3.html in section where explain fields operations ////// function inverseArray(pVals, n) { @@ -707,4 +707,4 @@ contract PlonkVerifier { } } -} \ No newline at end of file +} From a98f8360e233aa312b58a7cc5e3f2dd768946fe0 Mon Sep 17 00:00:00 2001 From: rebustron Date: Tue, 17 Dec 2024 10:00:08 +0100 Subject: [PATCH 29/35] fixed broken link plonk_verifier.sol.ejs --- .../templates/hashchecker/templates/plonk_verifier.sol.ejs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ws-templates/src/templates/hashchecker/templates/plonk_verifier.sol.ejs b/libs/remix-ws-templates/src/templates/hashchecker/templates/plonk_verifier.sol.ejs index 8b3ed1d109..963bade7f1 100644 --- a/libs/remix-ws-templates/src/templates/hashchecker/templates/plonk_verifier.sol.ejs +++ b/libs/remix-ws-templates/src/templates/hashchecker/templates/plonk_verifier.sol.ejs @@ -152,7 +152,7 @@ contract PlonkVerifier { /////// // Computes the inverse of an array of values - // See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations + // See https://vitalik.eth.limo/general/2018/07/21/starks_part_3.html in section where explain fields operations ////// function inverseArray(pVals, n) { @@ -707,4 +707,4 @@ contract PlonkVerifier { } } -} \ No newline at end of file +} From a85e268f0928d83fc571996547a727ed31142ab1 Mon Sep 17 00:00:00 2001 From: filip mertens Date: Tue, 17 Dec 2024 10:23:41 +0100 Subject: [PATCH 30/35] refactor environment explorer --- .../app/providers/environment-explorer.tsx | 278 +++--------------- apps/remix-ide/src/blockchain/blockchain.tsx | 4 + .../environment-explorer/src/index.ts | 2 + .../components/environment-explorer-ui.tsx | 111 +++++++ .../src/lib/types/index.ts | 45 +++ .../grid-view/src/lib/remix-ui-grid-cell.tsx | 8 +- tsconfig.paths.json | 5 +- 7 files changed, 213 insertions(+), 240 deletions(-) create mode 100644 libs/remix-ui/environment-explorer/src/index.ts create mode 100644 libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx create mode 100644 libs/remix-ui/environment-explorer/src/lib/types/index.ts diff --git a/apps/remix-ide/src/app/providers/environment-explorer.tsx b/apps/remix-ide/src/app/providers/environment-explorer.tsx index facc93e4d8..cbf57ec29c 100644 --- a/apps/remix-ide/src/app/providers/environment-explorer.tsx +++ b/apps/remix-ide/src/app/providers/environment-explorer.tsx @@ -1,11 +1,8 @@ import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' -import { CustomTooltip, PluginViewWrapper } from '@remix-ui/helper' -import { RemixUIGridView } from '@remix-ui/remix-ui-grid-view' -import { RemixUIGridSection } from '@remix-ui/remix-ui-grid-section' -import { RemixUIGridCell } from '@remix-ui/remix-ui-grid-cell' +import { PluginViewWrapper } from '@remix-ui/helper' import './style/environment-explorer.css' -import type { Provider } from '../../blockchain/blockchain' +import { EnvironmentExplorerUI, Provider } from '@remix-ui/environment-explorer' import * as packageJson from '../../../../../package.json' @@ -25,44 +22,31 @@ const profile = { methods: [] } -type ProvidersSection = `Injected` | 'Remix VMs' | 'Externals' | 'Remix forked VMs' | 'Saved VM States' +type EnvironmentExplorerState = { + providersFlat: { [key: string]: Provider }, + pinnedProviders: string[], +} export class EnvironmentExplorer extends ViewPlugin { - providers: { [key in ProvidersSection]: Provider[] } - providersFlat: { [key: string]: Provider } - pinnedProviders: string[] - dispatch: React.Dispatch = () => {} - + dispatch: React.Dispatch = () => { } + state: EnvironmentExplorerState constructor() { super(profile) - this.providersFlat = {} - this.providers = { - 'Injected': [], - 'Remix VMs': [], - 'Saved VM States': [], - 'Remix forked VMs': [], - 'Externals': [] + this.state = { + providersFlat: {}, + pinnedProviders: [], } } async onActivation(): Promise { - this.providersFlat = await this.call('blockchain', 'getAllProviders') - this.pinnedProviders = await this.call('blockchain', 'getPinnedProviders') - this.renderComponent() + this.on('blockchain', 'providersChanged', this.updateProviders.bind(this)) + await this.updateProviders() } - addProvider (provider: Provider) { - if (provider.isInjected) { - this.providers['Injected'].push(provider) - } else if (provider.isForkedVM) { - this.providers['Remix forked VMs'].push(provider) - } else if (provider.isVM) { - this.providers['Remix VMs'].push(provider) - } else if (provider.isSavedState) { - this.providers['Saved VM States'].push(provider) - } else { - this.providers['Externals'].push(provider) - } + async updateProviders() { + this.state.providersFlat = await this.call('blockchain', 'getAllProviders') + this.state.pinnedProviders = await this.call('blockchain', 'getPinnedProviders') + this.renderComponent() } setDispatch(dispatch: React.Dispatch): void { @@ -77,215 +61,33 @@ export class EnvironmentExplorer extends ViewPlugin { ) } + + async pinStateCallback(provider: Provider, pinned: boolean) { + if (pinned) { + this.emit('providerPinned', provider.name, provider) + this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) + } else { + const providerName = await this.call('blockchain', 'getProvider') + if (providerName !== provider.name) { + this.emit('providerUnpinned', provider.name, provider) + this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) + return true + } else { + this.call('notification', 'toast', 'Cannot unpin the current selected provider') + return false + } + } + } + renderComponent() { this.dispatch({ - ...this + ...this.state }) } - updateComponent(state: any) { - this.providers = { - 'Injected': [], - 'Remix VMs': [], - 'Saved VM States': [], - 'Externals': [], - 'Remix forked VMs': [] - } - for (const [key, provider] of Object.entries(this.providersFlat)) { - this.addProvider(provider) - } - return ( - - - {this.providers['Injected'].map(provider => { - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
{provider.description}
-
- })} -
- {this.providers['Remix VMs'].map(provider => { - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
{provider.description}
-
- })}
- {this.providers['Saved VM States'].map(provider => { - const { latestBlock, timestamp } = JSON.parse(provider.description) - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
Latest Block: {parseInt(latestBlock)}
- -
Saved at: {(new Date(timestamp)).toDateString()}
-
-
- })}
- {this.providers['Remix forked VMs'].map(provider => { - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
{provider.description}
-
- })}
- {this.providers['Externals'].map(provider => { - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
{provider.description}
-
- })}
-
- ) + updateComponent(state: EnvironmentExplorerState) { + return (<> + + ) } } diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index d5832e9ff4..6d3958a064 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -146,6 +146,7 @@ export class Blockchain extends Plugin { this.pinnedProviders.push(name) this.call('config', 'setAppParameter', 'settings/pinned-providers', JSON.stringify(this.pinnedProviders)) _paq.push(['trackEvent', 'blockchain', 'providerPinned', name]) + this.emit('providersChanged') }) this.on('environmentExplorer', 'providerUnpinned', (name, provider) => { @@ -154,6 +155,7 @@ export class Blockchain extends Plugin { this.pinnedProviders.splice(index, 1) this.call('config', 'setAppParameter', 'settings/pinned-providers', JSON.stringify(this.pinnedProviders)) _paq.push(['trackEvent', 'blockchain', 'providerUnpinned', name]) + this.emit('providersChanged') }) this.call('config', 'getAppParameter', 'settings/pinned-providers').then((providers) => { @@ -665,10 +667,12 @@ export class Blockchain extends Plugin { addProvider(provider: Provider) { if (this.pinnedProviders.includes(provider.name)) this.emit('shouldAddProvidertoUdapp', provider.name, provider) this.executionContext.addProvider(provider) + this.emit('providersChanged') } removeProvider(name) { this.executionContext.removeProvider(name) + this.emit('providersChanged') } getAllProviders() { diff --git a/libs/remix-ui/environment-explorer/src/index.ts b/libs/remix-ui/environment-explorer/src/index.ts new file mode 100644 index 0000000000..6b3a3132fa --- /dev/null +++ b/libs/remix-ui/environment-explorer/src/index.ts @@ -0,0 +1,2 @@ +export * from './lib/types' +export { EnvironmentExplorerUI } from './lib/components/environment-explorer-ui' \ No newline at end of file diff --git a/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx b/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx new file mode 100644 index 0000000000..be13e52982 --- /dev/null +++ b/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx @@ -0,0 +1,111 @@ +// eslint-disable-next-line no-use-before-define +import React, { useEffect, useState } from 'react' +import { environmentExplorerUIGridSections, environmentExplorerUIProps } from '../types' +import { RemixUIGridCell, RemixUIGridSection, RemixUIGridView } from '@remix-ui/remix-ui-grid-view' +import { CustomTooltip } from '@remix-ui/helper' + +const defaultSections: environmentExplorerUIGridSections = { + Injected: { + title: 'Deploy using a Browser Extension.', + keywords: ['Injected'], + providers: [], + filterFn: (provider) => provider.isInjected + }, + 'Remix VMs': { + title: 'Deploy to an In-browser Virtual Machine.', + keywords: ['Remix VMs'], + providers: [], + filterFn: (provider) => provider.isVM + }, + 'Saved VM States': { + title: 'Deploy to an In-browser Saved VM State.', + keywords: ['Saved VM States'], + providers: [], + filterFn: (provider) => provider.isSavedState, + descriptionFn: (provider) => { + const { latestBlock, timestamp } = JSON.parse(provider.description) + return ( + <> +
Latest Block: {parseInt(latestBlock)}
+ +
Saved at: {(new Date(timestamp)).toDateString()}
+
+ ) + } + }, + 'Remix forked VMs': { + title: 'Deploy to a Remix forked Virtual Machine.', + keywords: ['Remix forked VMs'], + providers: [], + filterFn: (provider) => provider.isForkedVM + }, + 'Externals': { + title: 'Deploy to an external Provider.', + keywords: ['Externals'], + providers: [], + filterFn: (provider) => (!provider.isInjected && !provider.isVM && !provider.isSavedState && !provider.isForkedVM) + }, +} +export const EnvironmentExplorerUI = (props: environmentExplorerUIProps) => { + + const [sections, setSections] = useState(defaultSections) + const { state, pinStateCallback, profile } = props + + useEffect(() => { + + setSections((prevSections) => { + const newSections = { ...prevSections } + Object.keys(newSections).forEach((section) => { + newSections[section].providers = Object.values(state.providersFlat).filter(newSections[section].filterFn) + }) + return newSections + }) + }, [state]) + + return ( + <> + { + Object.values(sections).length && Object.values(sections).map((section) => ( + + {section.providers.map(provider => { + return { + await pinStateCallback(provider, pinned) + }} + > +
{(section.descriptionFn && section.descriptionFn(provider)) || provider.description}
+
+ })} +
+ )) + } +
+ + ) +} \ No newline at end of file diff --git a/libs/remix-ui/environment-explorer/src/lib/types/index.ts b/libs/remix-ui/environment-explorer/src/lib/types/index.ts new file mode 100644 index 0000000000..61685a5f36 --- /dev/null +++ b/libs/remix-ui/environment-explorer/src/lib/types/index.ts @@ -0,0 +1,45 @@ +import { Plugin } from '@remixproject/engine' +import { Profile } from '@remixproject/plugin-utils' + +export type ProvidersSection = `Injected` | 'Remix VMs' | 'Externals' | 'Remix forked VMs' | 'Saved VM States' + +export type environmentExplorerUIProps = { + state: { + providersFlat: { [key: string]: Provider } + pinnedProviders: string[] + } + pinStateCallback (provider: Provider, pinned: boolean): Promise + profile: Profile +} + +export type environmentExplorerUIGridSection = { + title: string + keywords: string[], + providers: Provider[] + filterFn: (provider: Provider) => boolean + descriptionFn?: (provider: Provider) => string | JSX.Element | null +} + +export type environmentExplorerUIGridSections = { + [key in ProvidersSection]: environmentExplorerUIGridSection +} + +export type Provider = { + options: { [key: string]: string } + dataId: string + name: string + displayName: string + logo?: string, + logos?: string[], + fork: string + description?: string + isInjected: boolean + isVM: boolean + isSavedState: boolean + isForkedVM: boolean + title: string + init: () => Promise + provider: { + sendAsync: (payload: any) => Promise + } +} \ No newline at end of file diff --git a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx index f215b9ab53..3c66f9703d 100644 --- a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx +++ b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx @@ -54,6 +54,12 @@ export const RemixUIGridCell = (props: RemixUIGridCellProps) => { setAnyEnabled(enabled) }, [filterCon, props.tagList]) + useEffect(() => { + if(props.pinned!== pinned) { + setPinned(props.pinned) + } + },[props.pinned]) + /*const listenOnExpand = (key) => { if (key === props.key) setExpand(props.toggleExpandView) console.log('expand ----> ', key) @@ -86,7 +92,7 @@ export const RemixUIGridCell = (props: RemixUIGridCellProps) => { : <> } - { props.logos && props.logos.map((logo) => )} + { props.logos && props.logos.map((logo, index) => )} { props.title && Date: Tue, 17 Dec 2024 15:39:26 +0100 Subject: [PATCH 31/35] lint --- apps/remix-ide/src/app/providers/environment-explorer.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/remix-ide/src/app/providers/environment-explorer.tsx b/apps/remix-ide/src/app/providers/environment-explorer.tsx index cbf57ec29c..a38c0d74d3 100644 --- a/apps/remix-ide/src/app/providers/environment-explorer.tsx +++ b/apps/remix-ide/src/app/providers/environment-explorer.tsx @@ -61,7 +61,6 @@ export class EnvironmentExplorer extends ViewPlugin { ) } - async pinStateCallback(provider: Provider, pinned: boolean) { if (pinned) { this.emit('providerPinned', provider.name, provider) From f72477cfd64022cdc32d56fc764200143f8c2807 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Wed, 18 Dec 2024 08:10:54 +0100 Subject: [PATCH 32/35] linting --- .../src/lib/components/environment-explorer-ui.tsx | 2 +- libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx b/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx index be13e52982..42c2835a41 100644 --- a/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx +++ b/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx @@ -78,7 +78,7 @@ export const EnvironmentExplorerUI = (props: environmentExplorerUIProps) => { title={profile.description} description="Select the providers and chains to include them in the ENVIRONMENT select box of the Deploy & Run Transactions plugin." >{ - Object.values(sections).length && Object.values(sections).map((section) => ( + Object.values(sections).length && Object.values(sections).map((section) => ( { }, [filterCon, props.tagList]) useEffect(() => { - if(props.pinned!== pinned) { + if (props.pinned!== pinned) { setPinned(props.pinned) } },[props.pinned]) From b48d376865facd115572a344dcb9d36d75d403bd Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Wed, 18 Dec 2024 08:26:06 +0100 Subject: [PATCH 33/35] z index --- libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css index 760a85e1d6..3226d3c53f 100644 --- a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css +++ b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css @@ -31,6 +31,7 @@ right: 0.9rem; top: -0.7rem; background: transparent; + z-index: 1000; } .remixui_grid_cell_tags { From 5f202f32c423da2f0fd53f6ff6c5be5fe267e20c Mon Sep 17 00:00:00 2001 From: FT <140458077+zeevick10@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:05:34 +0100 Subject: [PATCH 34/35] Update release-process.md --- release-process.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-process.md b/release-process.md index d66786d602..3443b2a083 100644 --- a/release-process.md +++ b/release-process.md @@ -49,7 +49,7 @@ This command will ask for a new version. This command uses `lerna` and is solely responsible for publishing all the remix libraries. It will ask for a new version of each library. Make sure you are logged in to NPM. -Once these commands run successfully, the version for each remix library will be updated to latest in the libs' package.json file. +Once these commands run successfully, the version for each remix library will be updated to the latest in the libs' package.json file. - Create and merge bump PR to master From 144f424329c53fd17a5d9030c235894033063363 Mon Sep 17 00:00:00 2001 From: witty <131909329+0xwitty@users.noreply.github.com> Date: Wed, 18 Dec 2024 14:54:44 +0300 Subject: [PATCH 35/35] docs: Fix Typos and Grammar in Documentation Update team-best-practices.md --- apps/remix-ide/team-best-practices.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/team-best-practices.md b/apps/remix-ide/team-best-practices.md index 7517e3483c..2088cd5bf9 100644 --- a/apps/remix-ide/team-best-practices.md +++ b/apps/remix-ide/team-best-practices.md @@ -5,7 +5,7 @@ This document aims to address contributors best practices of the following repos - remix-ide https://github.com/ethereum/remix-project - remix-plugin https://github.com/ethereum/remix-plugin -This document is not in its final version, **a team meeting which aims to address new/old best practices, feedback, workflows, all kind of issues related to how the team work together occurs every 2 weeks.** +This document is not in its final version, **a team meeting which aims to address new/old best practices, feedback, workflows, all kind of issues related to how the team works together occurs every 2 weeks.** This document link to other specialised best practices (like coding best practices). Related links: @@ -122,9 +122,9 @@ Before starting to coding, we should ensure all devs / contributors are aware of - A milestone should **only** contain items we are sure to finish. - The end of a milestone trigger a new release. - - Milestone items and duration should take in account time spent in bugs fixing and support. + - Milestone items and duration should take into account time spent in bugs fixing and support. - The team should commit to the milestone duration. - - If a dev finish early he/she can help other to push remaining tasks. + - If a dev finish early he/she can help others to push remaining tasks. - If a dev finish early he/she can work on specifying / integrating the next milestone. - A milestone duration is fixed at the start of the milestone (but should better not exceed 1 month). - Progress and issues regarding a milestone are discussed on regular standups. @@ -146,7 +146,7 @@ Before starting to coding, we should ensure all devs / contributors are aware of - After a new release we should stay in alert for possible regression and better not release on Friday at 5pm :) ### 2) Community: - - Before the official release, we should select a group of power users and invite them to test and give feedbacks. + - Before the official release, we should select a group of power users and invite them to test and give feedback. - Users need to know upfront a new release is coming and we should prepare them for it by showcasing some new features they can expect and when it will happen (fixed date, published at least 1 week in advance). - Whenever we have a new release we have to communicate this efficiently (twitter, reddit, ...).