From 2069d768c7edfee1e2a00d36ed4a710f23d4b079 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 18 Mar 2022 18:38:53 +0100 Subject: [PATCH 01/14] activate hardhat provider at load --- .../src/app/tabs/abstract-provider.tsx | 123 ++++++++++++++++++ .../src/app/tabs/hardhat-provider.tsx | 106 +-------------- apps/remix-ide/src/app/udapp/run-tab.js | 8 +- apps/remix-ide/src/remixAppManager.js | 2 +- .../remix-ui/run-tab/src/lib/actions/index.ts | 3 +- libs/remix-ui/run-tab/src/lib/run-tab.tsx | 1 + .../run-tab/src/lib/types/run-tab.d.ts | 1 + 7 files changed, 137 insertions(+), 107 deletions(-) create mode 100644 apps/remix-ide/src/app/tabs/abstract-provider.tsx diff --git a/apps/remix-ide/src/app/tabs/abstract-provider.tsx b/apps/remix-ide/src/app/tabs/abstract-provider.tsx new file mode 100644 index 0000000000..90ba5af3b5 --- /dev/null +++ b/apps/remix-ide/src/app/tabs/abstract-provider.tsx @@ -0,0 +1,123 @@ +import * as packageJson from '../../../../../package.json' +import { Plugin } from '@remixproject/engine' +import { AppModal, AlertModal, ModalTypes } from '@remix-ui/app' +import React from 'react' // eslint-disable-line +import { Blockchain } from '../../blockchain/blockchain' +import { ethers } from 'ethers' + +const profile = { + name: 'hardhat-provider', + displayName: 'Hardhat Provider', + kind: 'provider', + description: 'Hardhat provider', + methods: ['sendAsync'], + version: packageJson.version +} + +type JsonDataRequest = { + id: number, + jsonrpc: string // version + method: string, + params: Array, +} + +type JsonDataResult = { + id: number, + jsonrpc: string // version + result: any +} + +type RejectRequest = (error: Error) => void +type SuccessRequest = (data: JsonDataResult) => void + +export abstract class AbstractProvider extends Plugin { + provider: ethers.providers.JsonRpcProvider + blocked: boolean + blockchain: Blockchain + defaultUrl: string + + constructor (profile, blockchain, defaultUrl) { + super(profile) + this.defaultUrl = defaultUrl + this.provider = null + this.blocked = false // used to block any call when trying to recover after a failed connection. + this.blockchain = blockchain + } + + abstract body(): JSX.Element + + onDeactivation () { + this.provider = null + this.blocked = false + } + + sendAsync (data: JsonDataRequest): Promise { + return new Promise(async (resolve, reject) => { + if (this.blocked) return reject(new Error('provider unable to connect')) + // If provider is not set, allow to open modal only when provider is trying to connect + if (!this.provider) { + let value: string + try { + value = await ((): Promise => { + return new Promise((resolve, reject) => { + const modalContent: AppModal = { + id: this.profile.name, + title: this.profile.displayName, + message: this.body(), + modalType: ModalTypes.prompt, + okLabel: 'OK', + cancelLabel: 'Cancel', + okFn: (value: string) => { + setTimeout(() => resolve(value), 0) + }, + cancelFn: () => { + setTimeout(() => reject(new Error('Canceled')), 0) + }, + hideFn: () => { + setTimeout(() => reject(new Error('Hide')), 0) + }, + defaultValue: this.defaultUrl + } + this.call('notification', 'modal', modalContent) + }) + })() + } catch (e) { + // the modal has been canceled/hide + return + } + this.provider = new ethers.providers.JsonRpcProvider(value) + this.sendAsyncInternal(data, resolve, reject) + } else { + this.sendAsyncInternal(data, resolve, reject) + } + }) + } + + private async sendAsyncInternal (data: JsonDataRequest, resolve: SuccessRequest, reject: RejectRequest): Promise { + if (this.provider) { + // Check the case where current environment is VM on UI and it still sends RPC requests + // This will be displayed on UI tooltip as 'cannot get account list: Environment Updated !!' + if (this.blockchain.getProvider() !== this.profile.displayName && data.method !== 'net_listening') return reject(new Error('Environment Updated !!')) + + try { + const result = await this.provider.send(data.method, data.params) + resolve({ jsonrpc: '2.0', result, id: data.id }) + } catch (error) { + this.blocked = true + const modalContent: AlertModal = { + id: this.profile.name, + title: this.profile.displayName, + message: `Error while connecting to the provider: ${error.message}`, + } + this.call('notification', 'alert', modalContent) + await this.call('udapp', 'setEnvironmentMode', { context: 'vm', fork: 'london' }) + this.provider = null + setTimeout(_ => { this.blocked = false }, 1000) // we wait 1 second for letting remix to switch to vm + reject(error) + } + } else { + const result = data.method === 'net_listening' ? 'canceled' : [] + resolve({ jsonrpc: '2.0', result: result, id: data.id }) + } + } +} diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.tsx b/apps/remix-ide/src/app/tabs/hardhat-provider.tsx index d17f4d1281..89a2156e82 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.tsx +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.tsx @@ -4,6 +4,7 @@ import { AppModal, AlertModal, ModalTypes } from '@remix-ui/app' import React from 'react' // eslint-disable-line import { Blockchain } from '../../blockchain/blockchain' import { ethers } from 'ethers' +import { AbstractProvider } from './abstract-provider' const profile = { name: 'hardhat-provider', @@ -14,41 +15,12 @@ const profile = { version: packageJson.version } -type JsonDataRequest = { - id: number, - jsonrpc: string // version - method: string, - params: Array, -} - -type JsonDataResult = { - id: number, - jsonrpc: string // version - result: any -} - -type RejectRequest = (error: Error) => void -type SuccessRequest = (data: JsonDataResult) => void - -export class HardhatProvider extends Plugin { - provider: ethers.providers.JsonRpcProvider - blocked: boolean - blockchain: Blockchain - target: String - +export class HardhatProvider extends AbstractProvider { constructor (blockchain) { - super(profile) - this.provider = null - this.blocked = false // used to block any call when trying to recover after a failed connection. - this.blockchain = blockchain + super(profile, blockchain, 'http://127.0.0.1:8545') } - onDeactivation () { - this.provider = null - this.blocked = false - } - - hardhatProviderDialogBody (): JSX.Element { + body (): JSX.Element { return (
Note: To run Hardhat network node on your system, go to hardhat project folder and run command:
npx hardhat node
@@ -57,74 +29,4 @@ export class HardhatProvider extends Plugin {
) } - - sendAsync (data: JsonDataRequest): Promise { - return new Promise(async (resolve, reject) => { - if (this.blocked) return reject(new Error('provider unable to connect')) - // If provider is not set, allow to open modal only when provider is trying to connect - if (!this.provider) { - let value: string - try { - value = await ((): Promise => { - return new Promise((resolve, reject) => { - const modalContent: AppModal = { - id: 'hardhatprovider', - title: 'Hardhat node request', - message: this.hardhatProviderDialogBody(), - modalType: ModalTypes.prompt, - okLabel: 'OK', - cancelLabel: 'Cancel', - okFn: (value: string) => { - setTimeout(() => resolve(value), 0) - }, - cancelFn: () => { - setTimeout(() => reject(new Error('Canceled')), 0) - }, - hideFn: () => { - setTimeout(() => reject(new Error('Hide')), 0) - }, - defaultValue: 'http://127.0.0.1:8545' - } - this.call('notification', 'modal', modalContent) - }) - })() - } catch (e) { - // the modal has been canceled/hide - return - } - this.provider = new ethers.providers.JsonRpcProvider(value) - this.sendAsyncInternal(data, resolve, reject) - } else { - this.sendAsyncInternal(data, resolve, reject) - } - }) - } - - private async sendAsyncInternal (data: JsonDataRequest, resolve: SuccessRequest, reject: RejectRequest): Promise { - if (this.provider) { - // Check the case where current environment is VM on UI and it still sends RPC requests - // This will be displayed on UI tooltip as 'cannot get account list: Environment Updated !!' - if (this.blockchain.getProvider() !== 'Hardhat Provider' && data.method !== 'net_listening') return reject(new Error('Environment Updated !!')) - - try { - const result = await this.provider.send(data.method, data.params) - resolve({ jsonrpc: '2.0', result, id: data.id }) - } catch (error) { - this.blocked = true - const modalContent: AlertModal = { - id: 'hardhatprovider', - title: 'Hardhat Provider', - message: `Error while connecting to the hardhat provider: ${error.message}`, - } - this.call('notification', 'alert', modalContent) - await this.call('udapp', 'setEnvironmentMode', { context: 'vm', fork: 'london' }) - this.provider = null - setTimeout(_ => { this.blocked = false }, 1000) // we wait 1 second for letting remix to switch to vm - reject(error) - } - } else { - const result = data.method === 'net_listening' ? 'canceled' : [] - resolve({ jsonrpc: '2.0', result: result, id: data.id }) - } - } } \ No newline at end of file diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index 313161b121..4868ff2ade 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -39,7 +39,6 @@ export class RunTab extends ViewPlugin { this.el = document.createElement('div') } - setupEvents () { this.blockchain.events.on('newTransaction', (tx, receipt) => { this.emit('newTransaction', tx, receipt) @@ -93,9 +92,12 @@ export class RunTab extends ViewPlugin { return
} - onReady (api) { - this.REACT_API = api + this.REACT_API = api + } + + onInitDone () { + this.call('manager', 'activatePlugin', 'hardhat-provider') } writeFile (fileName, content) { diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index e14e98d66f..53de9df3cc 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -8,7 +8,7 @@ const requiredModules = [ // services + layout views + system views 'manager', 'config', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme', 'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons', 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic', 'gistHandler', 'layout', - 'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'intelligentScriptExecutor'] + 'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'hardhat-provider', 'intelligentScriptExecutor'] const dependentModules = ['git', 'hardhat', 'truffle', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd) diff --git a/libs/remix-ui/run-tab/src/lib/actions/index.ts b/libs/remix-ui/run-tab/src/lib/actions/index.ts index 6e0ebeae9c..329bb5ad2b 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/index.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/index.ts @@ -188,6 +188,7 @@ export const setGasFee = (value: number) => { const addPluginProvider = (profile) => { if (profile.kind === 'provider') { + console.log(profile); ((profile, app) => { const web3Provider = { async sendAsync (payload, callback) { @@ -232,8 +233,8 @@ export const setNetworkNameFromProvider = (networkName: string) => { } const addExternalProvider = (network) => { + console.log('adding ext provider', network) dispatch(addProvider(network)) - dispatch(displayPopUp(`${network.name} provider added`)) } const removeExternalProvider = (name) => { diff --git a/libs/remix-ui/run-tab/src/lib/run-tab.tsx b/libs/remix-ui/run-tab/src/lib/run-tab.tsx index 2b94114799..c8c74966c8 100644 --- a/libs/remix-ui/run-tab/src/lib/run-tab.tsx +++ b/libs/remix-ui/run-tab/src/lib/run-tab.tsx @@ -61,6 +61,7 @@ export function RunTabUI (props: RunTabProps) { useEffect(() => { initRunTab(plugin)(dispatch) + plugin.onInitDone() }, [plugin]) useEffect(() => { diff --git a/libs/remix-ui/run-tab/src/lib/types/run-tab.d.ts b/libs/remix-ui/run-tab/src/lib/types/run-tab.d.ts index 37783c2119..cecdbe121d 100644 --- a/libs/remix-ui/run-tab/src/lib/types/run-tab.d.ts +++ b/libs/remix-ui/run-tab/src/lib/types/run-tab.d.ts @@ -34,6 +34,7 @@ export class RunTab extends ViewPlugin { udappUI: any; renderComponent(): void; onReady(api: any): void; + onInitDone(): void; recorder: Recorder; } import { ViewPlugin } from "@remixproject/engine-web/lib/view"; From cfd9dc778eb52f5d35437a659fe9401851556f5a Mon Sep 17 00:00:00 2001 From: yann300 Date: Sat, 19 Mar 2022 01:17:21 +0100 Subject: [PATCH 02/14] add ganache provider --- apps/remix-ide/src/app.js | 3 ++ .../src/app/tabs/ganache-provider.tsx | 33 +++++++++++++++++++ apps/remix-ide/src/app/udapp/run-tab.js | 5 +-- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 apps/remix-ide/src/app/tabs/ganache-provider.tsx diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 1a295fb793..8b9197f5d5 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -26,6 +26,7 @@ import { Layout } from './app/panels/layout' import { NotificationPlugin } from './app/plugins/notification' import { Blockchain } from './blockchain/blockchain.js' import { HardhatProvider } from './app/tabs/hardhat-provider' +import { GanacheProvider } from './app/tabs/ganache-provider' const isElectron = require('is-electron') @@ -174,6 +175,7 @@ class AppComponent { // ----------------- represent the current selected web3 provider ---- const web3Provider = new Web3ProviderModule(blockchain) const hardhatProvider = new HardhatProvider(blockchain) + const ganacheProvider = new GanacheProvider(blockchain) // ----------------- convert offset to line/column service ----------- const offsetToLineColumnConverter = new OffsetToLineColumnConverter() Registry.getInstance().put({ @@ -229,6 +231,7 @@ class AppComponent { dGitProvider, storagePlugin, hardhatProvider, + ganacheProvider, this.walkthroughService, ]) diff --git a/apps/remix-ide/src/app/tabs/ganache-provider.tsx b/apps/remix-ide/src/app/tabs/ganache-provider.tsx new file mode 100644 index 0000000000..85b018bf1c --- /dev/null +++ b/apps/remix-ide/src/app/tabs/ganache-provider.tsx @@ -0,0 +1,33 @@ +import * as packageJson from '../../../../../package.json' +import { Plugin } from '@remixproject/engine' +import { AppModal, AlertModal, ModalTypes } from '@remix-ui/app' +import React from 'react' // eslint-disable-line +import { Blockchain } from '../../blockchain/blockchain' +import { ethers } from 'ethers' +import { AbstractProvider } from './abstract-provider' + +const profile = { + name: 'ganache-provider', + displayName: 'Ganache', + kind: 'provider', + description: 'Ganache', + methods: ['sendAsync'], + version: packageJson.version +} + +export class GanacheProvider extends AbstractProvider { + constructor (blockchain) { + super(profile, blockchain, 'http://127.0.0.1:8545') + } + + body (): JSX.Element { + return ( +
Note: To run Ganache on your system, run +
npm install -g ganache
+
ganache
+ For more info, visit: Ganache Documentation +
Ganache JSON-RPC Endpoint:
+
+ ) + } +} \ No newline at end of file diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index 4868ff2ade..5573ea345d 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -96,8 +96,9 @@ export class RunTab extends ViewPlugin { this.REACT_API = api } - onInitDone () { - this.call('manager', 'activatePlugin', 'hardhat-provider') + async onInitDone () { + await this.call('manager', 'activatePlugin', 'hardhat-provider') + await this.call('manager', 'activatePlugin', 'ganache-provider') } writeFile (fileName, content) { From 6bdc38008e479937c95ee6135f7da2ae692d98da Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 21 Mar 2022 14:20:10 +0100 Subject: [PATCH 03/14] update ganache & add walletconnect --- apps/remix-ide/src/app/tabs/ganache-provider.tsx | 2 +- apps/remix-ide/src/app/udapp/run-tab.js | 14 ++++++++++++++ apps/remix-ide/src/remixAppManager.js | 1 + apps/remix-ide/src/remixEngine.js | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/ganache-provider.tsx b/apps/remix-ide/src/app/tabs/ganache-provider.tsx index 85b018bf1c..b73cb18786 100644 --- a/apps/remix-ide/src/app/tabs/ganache-provider.tsx +++ b/apps/remix-ide/src/app/tabs/ganache-provider.tsx @@ -8,7 +8,7 @@ import { AbstractProvider } from './abstract-provider' const profile = { name: 'ganache-provider', - displayName: 'Ganache', + displayName: 'Ganache Provider', kind: 'provider', description: 'Ganache', methods: ['sendAsync'], diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index 5573ea345d..25450e5bea 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -99,6 +99,20 @@ export class RunTab extends ViewPlugin { async onInitDone () { await this.call('manager', 'activatePlugin', 'hardhat-provider') await this.call('manager', 'activatePlugin', 'ganache-provider') + const udapp = this + await this.call('blockchain', 'addProvider', { + name: 'Wallet Connect', + provider: { + async sendAsync (payload, callback) { + try { + const result = await udapp.call('walletconnect', 'sendAsync', payload) + callback(null, result) + } catch (e) { + callback(e) + } + } + } + }) } writeFile (fileName, content) { diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 53de9df3cc..cc55152d4b 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -133,6 +133,7 @@ export class RemixAppManager extends PluginManager { } } return plugins.map(plugin => { + if (plugin.name === 'walletconnect') plugin.url = 'http://127.0.0.1:8081' return new IframePlugin(plugin) // return new IframeReactPlugin(plugin) }) diff --git a/apps/remix-ide/src/remixEngine.js b/apps/remix-ide/src/remixEngine.js index 765fb7626d..9d34b58bf5 100644 --- a/apps/remix-ide/src/remixEngine.js +++ b/apps/remix-ide/src/remixEngine.js @@ -18,6 +18,7 @@ export class RemixEngine extends Engine { if (name === 'notification') return { queueTimeout: 60000 * 4 } if (name === 'sourcify') return { queueTimeout: 60000 * 4 } if (name === 'fetchAndCompile') return { queueTimeout: 60000 * 4 } + if (name === 'walletconnect') return { queueTimeout: 60000 * 4 } return { queueTimeout: 10000 } } From 18d7a92995fd8f4033c11e187b440f80d409b37a Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 21 Mar 2022 17:40:30 +0100 Subject: [PATCH 04/14] add provider from run ad deploy plugin --- apps/remix-ide/src/app/udapp/run-tab.js | 31 +++++++++++++++++-- apps/remix-ide/src/blockchain/blockchain.js | 2 +- apps/remix-ide/src/remixAppManager.js | 3 +- .../remix-ui/run-tab/src/lib/actions/index.ts | 27 ---------------- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index 25450e5bea..f2d419bbd1 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -97,9 +97,36 @@ export class RunTab extends ViewPlugin { } async onInitDone () { - await this.call('manager', 'activatePlugin', 'hardhat-provider') - await this.call('manager', 'activatePlugin', 'ganache-provider') const udapp = this + + await this.call('blockchain', 'addProvider', { + name: 'Hardhat Provider', + provider: { + async sendAsync (payload, callback) { + try { + const result = await udapp.call('hardhat-provider', 'sendAsync', payload) + callback(null, result) + } catch (e) { + callback(e) + } + } + } + }) + + await this.call('blockchain', 'addProvider', { + name: 'Ganache Provider', + provider: { + async sendAsync (payload, callback) { + try { + const result = await udapp.call('ganache-provider', 'sendAsync', payload) + callback(null, result) + } catch (e) { + callback(e) + } + } + } + }) + await this.call('blockchain', 'addProvider', { name: 'Wallet Connect', provider: { diff --git a/apps/remix-ide/src/blockchain/blockchain.js b/apps/remix-ide/src/blockchain/blockchain.js index 705c3089bd..b49b5b3ef2 100644 --- a/apps/remix-ide/src/blockchain/blockchain.js +++ b/apps/remix-ide/src/blockchain/blockchain.js @@ -22,7 +22,7 @@ const profile = { name: 'blockchain', displayName: 'Blockchain', description: 'Blockchain - Logic', - methods: ['getCode', 'getTransactionReceipt'], + methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider'], version: packageJson.version } diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index cc55152d4b..0313d1baaa 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -13,7 +13,7 @@ const requiredModules = [ // services + layout views + system views const dependentModules = ['git', 'hardhat', 'truffle', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd) export function isNative (name) { - const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification'] + const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification', 'hardhat-provider', 'ganache-provider'] return nativePlugins.includes(name) || requiredModules.includes(name) } @@ -133,7 +133,6 @@ export class RemixAppManager extends PluginManager { } } return plugins.map(plugin => { - if (plugin.name === 'walletconnect') plugin.url = 'http://127.0.0.1:8081' return new IframePlugin(plugin) // return new IframeReactPlugin(plugin) }) diff --git a/libs/remix-ui/run-tab/src/lib/actions/index.ts b/libs/remix-ui/run-tab/src/lib/actions/index.ts index 329bb5ad2b..fa4a0a54ac 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/index.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/index.ts @@ -64,10 +64,6 @@ const setupEvents = () => { plugin.blockchain.event.register('removeProvider', name => removeExternalProvider(name)) - plugin.on('manager', 'pluginActivated', addPluginProvider.bind(plugin)) - - plugin.on('manager', 'pluginDeactivated', removePluginProvider.bind(plugin)) - plugin.on('solidity', 'compilationFinished', (file, source, languageVersion, data, input, version) => broadcastCompilationResult(file, source, languageVersion, data, input)) plugin.on('vyper', 'compilationFinished', (file, source, languageVersion, data) => broadcastCompilationResult(file, source, languageVersion, data)) @@ -186,29 +182,6 @@ export const setGasFee = (value: number) => { dispatch(setGasLimit(value)) } -const addPluginProvider = (profile) => { - if (profile.kind === 'provider') { - console.log(profile); - ((profile, app) => { - const web3Provider = { - async sendAsync (payload, callback) { - try { - const result = await app.call(profile.name, 'sendAsync', payload) - callback(null, result) - } catch (e) { - callback(e) - } - } - } - app.blockchain.addProvider({ name: profile.displayName, provider: web3Provider }) - })(profile, plugin) - } -} - -const removePluginProvider = (profile) => { - if (profile.kind === 'provider') plugin.blockchain.removeProvider(profile.displayName) -} - const setFinalContext = () => { // set the final context. Cause it is possible that this is not the one we've originaly selected const value = _getProviderDropdownValue() From d582c3f0e1893f405d0643f27f2da8b645506a05 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 23 Mar 2022 11:03:12 +0100 Subject: [PATCH 05/14] remove uneeded code --- apps/remix-ide/src/app/tabs/abstract-provider.tsx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/abstract-provider.tsx b/apps/remix-ide/src/app/tabs/abstract-provider.tsx index 90ba5af3b5..f16187711e 100644 --- a/apps/remix-ide/src/app/tabs/abstract-provider.tsx +++ b/apps/remix-ide/src/app/tabs/abstract-provider.tsx @@ -1,19 +1,8 @@ -import * as packageJson from '../../../../../package.json' import { Plugin } from '@remixproject/engine' import { AppModal, AlertModal, ModalTypes } from '@remix-ui/app' -import React from 'react' // eslint-disable-line import { Blockchain } from '../../blockchain/blockchain' import { ethers } from 'ethers' -const profile = { - name: 'hardhat-provider', - displayName: 'Hardhat Provider', - kind: 'provider', - description: 'Hardhat provider', - methods: ['sendAsync'], - version: packageJson.version -} - type JsonDataRequest = { id: number, jsonrpc: string // version From 2d455859860940449b715a5d844ce3fed03666a7 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 23 Mar 2022 11:25:44 +0100 Subject: [PATCH 06/14] add test for local provider --- .../remix-ide-e2e/src/tests/providers.test.ts | 34 +++++++++++++++++++ package.json | 1 + 2 files changed, 35 insertions(+) create mode 100644 apps/remix-ide-e2e/src/tests/providers.test.ts diff --git a/apps/remix-ide-e2e/src/tests/providers.test.ts b/apps/remix-ide-e2e/src/tests/providers.test.ts new file mode 100644 index 0000000000..b929c19d02 --- /dev/null +++ b/apps/remix-ide-e2e/src/tests/providers.test.ts @@ -0,0 +1,34 @@ +'use strict' +import { NightwatchBrowser } from 'nightwatch' +import init from '../helpers/init' + +module.exports = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + init(browser, done, 'http://127.0.0.1:8080', false) + }, + + 'Should switch to ganache provider, set a custom URL and fail to connect': function (browser: NightwatchBrowser) { + browser.waitForElementVisible('div[data-id="remixIdeIconPanel"]', 10000) + .clickLaunchIcon('udapp') + .click('*[data-id="Ganache Provider"]') + .waitForElementVisible('*[data-id="ganache-providerModalDialogModalBody-react"]') + .execute(() => { + (document.querySelector('*[data-id="ganache-providerModalDialogModalBody-react"] input') as any).focus() + }, [], () => {}) + .clearValue('*[data-id="ganache-providerModalDialogModalBody-react"] input') + .setValue('*[data-id="ganache-providerModalDialogModalBody-react"] input', 'http://127.0.0.1:8084') + .modalFooterOKClick('ganache-provider') + .waitForElementContainsText('*[data-id="ganache-providerModalDialogModalBody-react"]', 'Error while connecting to the provider') + .modalFooterOKClick('ganache-provider') + .waitForElementNotVisible('*[data-id="ganache-providerModalDialogModalBody-react"]') + }, + + 'Should switch to ganache provider, use the default ganache URL and succeed to connect': function (browser: NightwatchBrowser) { + browser.click('*[data-id="Ganache Provider"]') + .waitForElementVisible('*[data-id="ganache-providerModalDialogModalBody-react"]') + .execute(() => { + (document.querySelector('*[data-id="ganache-providerModalDialogModalBody-react"] input') as any).focus() + }, [], () => {}) + .waitForElementContainsText('*[data-id="settingsNetworkEnv"]', 'Custom (') + } +} diff --git a/package.json b/package.json index 16d9ea14b8..dd62ad1a90 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "nightwatch_local_migrate_filesystem": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/migrateFileSystem.test.js --env=chrome", "nightwatch_local_stress_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stressEditor.test.js --env=chromeDesktop", "nightwatch_local_search": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/search.test.js --env=chromeDesktop", + "nightwatch_local_search": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/providers.test.js --env=chromeDesktop", "onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint", "remixd": "nx build remixd && chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js -s ./apps/remix-ide/contracts --remix-ide http://127.0.0.1:8080", "selenium": "selenium-standalone start", From 0ed53b53bd19b354fcfda9baeed0be05348291ea Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 23 Mar 2022 12:08:44 +0100 Subject: [PATCH 07/14] fix linting --- apps/remix-ide/src/app/udapp/run-tab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index f2d419bbd1..0f59ddd962 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -97,7 +97,7 @@ export class RunTab extends ViewPlugin { } async onInitDone () { - const udapp = this + const udapp = this // eslint-disable-line await this.call('blockchain', 'addProvider', { name: 'Hardhat Provider', From 9b29cfe1d39b8cfe0c5b0a3c147d6a406e8fb5f8 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 23 Mar 2022 12:23:00 +0100 Subject: [PATCH 08/14] fix test --- apps/remix-ide-e2e/src/tests/providers.test.ts | 1 + libs/remix-ui/run-tab/src/lib/actions/index.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/providers.test.ts b/apps/remix-ide-e2e/src/tests/providers.test.ts index b929c19d02..de03803e38 100644 --- a/apps/remix-ide-e2e/src/tests/providers.test.ts +++ b/apps/remix-ide-e2e/src/tests/providers.test.ts @@ -21,6 +21,7 @@ module.exports = { .waitForElementContainsText('*[data-id="ganache-providerModalDialogModalBody-react"]', 'Error while connecting to the provider') .modalFooterOKClick('ganache-provider') .waitForElementNotVisible('*[data-id="ganache-providerModalDialogModalBody-react"]') + .pause(1000) }, 'Should switch to ganache provider, use the default ganache URL and succeed to connect': function (browser: NightwatchBrowser) { diff --git a/libs/remix-ui/run-tab/src/lib/actions/index.ts b/libs/remix-ui/run-tab/src/lib/actions/index.ts index fa4a0a54ac..030f0669fa 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/index.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/index.ts @@ -206,7 +206,6 @@ export const setNetworkNameFromProvider = (networkName: string) => { } const addExternalProvider = (network) => { - console.log('adding ext provider', network) dispatch(addProvider(network)) } From c3ca6aebd69bf93182dd2864bbf49e88c194794d Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 23 Mar 2022 12:37:49 +0100 Subject: [PATCH 09/14] fix e2e --- apps/remix-ide-e2e/src/tests/plugin_api.ts | 2 +- apps/remix-ide-e2e/src/tests/providers.test.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/plugin_api.ts b/apps/remix-ide-e2e/src/tests/plugin_api.ts index 1a8c9ab896..07fb7e033d 100644 --- a/apps/remix-ide-e2e/src/tests/plugin_api.ts +++ b/apps/remix-ide-e2e/src/tests/plugin_api.ts @@ -358,7 +358,7 @@ module.exports = { .scrollAndClick('[data-id="pluginManagerComponentActivateButtonhardhat-provider"]') .clickLaunchIcon('udapp') .click('*[data-id="Hardhat Provider"]') - .modalFooterOKClick('hardhatprovider') + .modalFooterOKClick('hardhat-provider') .waitForElementContainsText('*[data-id="settingsNetworkEnv"]', 'Custom') // e.g Custom (1337) network .clickLaunchIcon('localPlugin') .useXpath() diff --git a/apps/remix-ide-e2e/src/tests/providers.test.ts b/apps/remix-ide-e2e/src/tests/providers.test.ts index de03803e38..8bbfa7636b 100644 --- a/apps/remix-ide-e2e/src/tests/providers.test.ts +++ b/apps/remix-ide-e2e/src/tests/providers.test.ts @@ -27,9 +27,7 @@ module.exports = { 'Should switch to ganache provider, use the default ganache URL and succeed to connect': function (browser: NightwatchBrowser) { browser.click('*[data-id="Ganache Provider"]') .waitForElementVisible('*[data-id="ganache-providerModalDialogModalBody-react"]') - .execute(() => { - (document.querySelector('*[data-id="ganache-providerModalDialogModalBody-react"] input') as any).focus() - }, [], () => {}) + .modalFooterOKClick('ganache-provider') .waitForElementContainsText('*[data-id="settingsNetworkEnv"]', 'Custom (') } } From 27dafb54287ece109d9f08d45b28924bdb35025b Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 30 Mar 2022 12:17:30 +0200 Subject: [PATCH 10/14] fix cancel a connection to a web3 provider --- apps/remix-ide/src/app/tabs/abstract-provider.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/abstract-provider.tsx b/apps/remix-ide/src/app/tabs/abstract-provider.tsx index f16187711e..0e97180747 100644 --- a/apps/remix-ide/src/app/tabs/abstract-provider.tsx +++ b/apps/remix-ide/src/app/tabs/abstract-provider.tsx @@ -72,8 +72,10 @@ export abstract class AbstractProvider extends Plugin { })() } catch (e) { // the modal has been canceled/hide + const result = data.method === 'net_listening' ? 'canceled' : [] + resolve({ jsonrpc: '2.0', result: result, id: data.id }) return - } + } this.provider = new ethers.providers.JsonRpcProvider(value) this.sendAsyncInternal(data, resolve, reject) } else { From 2bbf7ecd576f849fdfd359c46a6bc5c4a0f9c8de Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 5 Apr 2022 13:08:37 +0200 Subject: [PATCH 11/14] fix e2e --- apps/remix-ide-e2e/src/tests/plugin_api.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/plugin_api.ts b/apps/remix-ide-e2e/src/tests/plugin_api.ts index 07fb7e033d..5c189a72c3 100644 --- a/apps/remix-ide-e2e/src/tests/plugin_api.ts +++ b/apps/remix-ide-e2e/src/tests/plugin_api.ts @@ -355,7 +355,6 @@ module.exports = { .frameParent() .useCss() .clickLaunchIcon('pluginManager') - .scrollAndClick('[data-id="pluginManagerComponentActivateButtonhardhat-provider"]') .clickLaunchIcon('udapp') .click('*[data-id="Hardhat Provider"]') .modalFooterOKClick('hardhat-provider') From 5d16f532af32312c3e194728f96637cac9e0a396 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 6 Apr 2022 09:57:44 +0200 Subject: [PATCH 12/14] update label --- apps/remix-ide/src/blockchain/execution-context.js | 2 +- libs/remix-ui/helper/src/lib/helper-components.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index 6f4a615b18..291475bcbb 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -220,7 +220,7 @@ export class ExecutionContext { cb() } else { web3.setProvider(oldProvider) - cb('Not possible to connect to the Web3 provider. Make sure the provider is running, a connection is open (via IPC or RPC) or that the provider plugin is properly configured.') + cb(`Not possible to connect to ${context}. Make sure the provider is running, a connection is open (via IPC or RPC) or that the provider plugin is properly configured.`) } }) } diff --git a/libs/remix-ui/helper/src/lib/helper-components.tsx b/libs/remix-ui/helper/src/lib/helper-components.tsx index a71950315e..e04e162ffc 100644 --- a/libs/remix-ui/helper/src/lib/helper-components.tsx +++ b/libs/remix-ui/helper/src/lib/helper-components.tsx @@ -64,7 +64,7 @@ export const envChangeNotification = (env: { context: string, fork: string }, fr { from + ' '} - is changing your environment to + set your environment to {env && env.context} From ada1a3a13f8056230d4d6301fcdce6093a1bff8f Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 6 Apr 2022 09:58:03 +0200 Subject: [PATCH 13/14] add matomo _paq --- apps/remix-ide/src/blockchain/execution-context.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index 291475bcbb..6688214efc 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -3,6 +3,7 @@ import Web3 from 'web3' import { execution } from '@remix-project/remix-lib' import EventManager from '../lib/events' +const _paq = window._paq = window._paq || [] let web3 @@ -128,6 +129,7 @@ export class ExecutionContext { } async executionContextChange (value, endPointUrl, confirmCb, infoCb, cb) { + _paq.push(['trackEvent', 'udapp', 'providerChanged', value.context]) const context = value.context if (!cb) cb = () => { /* Do nothing. */ } if (!confirmCb) confirmCb = () => { /* Do nothing. */ } From b2e7f75ba8d77e27c6a36499317ef9f1355f7e5f Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 6 Apr 2022 09:58:32 +0200 Subject: [PATCH 14/14] fix duplicate name --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dd62ad1a90..0155bc93f9 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "nightwatch_local_migrate_filesystem": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/migrateFileSystem.test.js --env=chrome", "nightwatch_local_stress_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stressEditor.test.js --env=chromeDesktop", "nightwatch_local_search": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/search.test.js --env=chromeDesktop", - "nightwatch_local_search": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/providers.test.js --env=chromeDesktop", + "nightwatch_local_providers": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/providers.test.js --env=chromeDesktop", "onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint", "remixd": "nx build remixd && chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js -s ./apps/remix-ide/contracts --remix-ide http://127.0.0.1:8080", "selenium": "selenium-standalone start",