Merge pull request #4026 from ethereum/add_ephemery_testnet

add ephemery provider
pull/4030/head
yann300 1 year ago committed by GitHub
commit 8379fed940
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 112
      apps/remix-ide/src/app.js
  2. 4
      apps/remix-ide/src/app/providers/injected-arbitrum-one-provider.tsx
  3. 8
      apps/remix-ide/src/app/providers/injected-custom-provider.tsx
  4. 17
      apps/remix-ide/src/app/providers/injected-ephemery-testnet-provider.tsx
  5. 4
      apps/remix-ide/src/app/providers/injected-optimism-provider.tsx
  6. 38
      apps/remix-ide/src/app/udapp/run-tab.js
  7. 142
      apps/remix-ide/src/remixAppManager.js

@ -41,6 +41,7 @@ import { InjectedProviderDefault } from './app/providers/injected-provider-defau
import {InjectedProviderTrustWallet} from './app/providers/injected-provider-trustwallet'
import {Injected0ptimismProvider} from './app/providers/injected-optimism-provider'
import {InjectedArbitrumOneProvider} from './app/providers/injected-arbitrum-one-provider'
import {InjectedEphemeryTestnetProvider} from './app/providers/injected-ephemery-testnet-provider'
import {FileDecorator} from './app/plugins/file-decorator'
import {CodeFormat} from './app/plugins/code-format'
import {SolidityUmlGen} from './app/plugins/solidity-umlgen'
@ -93,9 +94,7 @@ class AppComponent {
api: this._components.filesProviders.browser,
name: 'fileproviders/browser'
})
this._components.filesProviders.localhost = new RemixDProvider(
this.appManager
)
this._components.filesProviders.localhost = new RemixDProvider(this.appManager)
Registry.getInstance().put({
api: this._components.filesProviders.localhost,
name: 'fileproviders/localhost'
@ -119,7 +118,7 @@ class AppComponent {
this.panels = {}
this.workspace = pluginLoader.get()
this.engine = new RemixEngine()
this.engine.register(appManager);
this.engine.register(appManager)
const matomoDomains = {
'remix-alpha.ethereum.org': 27,
@ -127,15 +126,8 @@ class AppComponent {
'remix.ethereum.org': 23,
'6fd22d6fe5549ad4c4d8fd3ca0b7816b.mod': 35 // remix desktop
}
this.showMatamo =
matomoDomains[window.location.hostname] &&
!Registry.getInstance()
.get('config')
.api.exists('settings/matomo-analytics')
this.walkthroughService = new WalkthroughService(
appManager,
this.showMatamo
)
this.showMatamo = matomoDomains[window.location.hostname] && !Registry.getInstance().get('config').api.exists('settings/matomo-analytics')
this.walkthroughService = new WalkthroughService(appManager, this.showMatamo)
const hosts = ['127.0.0.1:8080', '192.168.0.101:8080', 'localhost:8080']
// workaround for Electron support
@ -221,9 +213,10 @@ class AppComponent {
const foundryProvider = new FoundryProvider(blockchain)
const externalHttpProvider = new ExternalHttpProvider(blockchain)
const trustWalletInjectedProvider = new InjectedProviderTrustWallet()
const defaultInjectedProvider = new InjectedProviderDefault
const defaultInjectedProvider = new InjectedProviderDefault()
const injected0ptimismProvider = new Injected0ptimismProvider()
const injectedArbitrumOneProvider = new InjectedArbitrumOneProvider()
const injectedEphemeryTestnetProvider = new InjectedEphemeryTestnetProvider()
// ----------------- convert offset to line/column service -----------
const offsetToLineColumnConverter = new OffsetToLineColumnConverter()
Registry.getInstance().put({
@ -233,11 +226,11 @@ class AppComponent {
// ----------------- run script after each compilation results -----------
const compileAndRun = new CompileAndRun()
// -------------------Terminal----------------------------------------
makeUdapp(blockchain, compilersArtefacts, domEl => terminal.logHtml(domEl))
makeUdapp(blockchain, compilersArtefacts, (domEl) => terminal.logHtml(domEl))
const terminal = new Terminal(
{appManager, blockchain},
{
getPosition: event => {
getPosition: (event) => {
const limitUp = 36
const limitDown = 20
const height = window.innerHeight
@ -299,6 +292,7 @@ class AppComponent {
trustWalletInjectedProvider,
injected0ptimismProvider,
injectedArbitrumOneProvider,
injectedEphemeryTestnetProvider,
this.walkthroughService,
search,
solidityumlgen,
@ -317,42 +311,18 @@ class AppComponent {
this.sidePanel = new SidePanel()
this.hiddenPanel = new HiddenPanel()
const pluginManagerComponent = new PluginManagerComponent(
appManager,
this.engine
)
const pluginManagerComponent = new PluginManagerComponent(appManager, this.engine)
const filePanel = new FilePanel(appManager)
const landingPage = new LandingPage(
appManager,
this.menuicons,
fileManager,
filePanel,
contentImport
)
this.settings = new SettingsTab(
Registry.getInstance().get('config').api,
editor,
appManager
)
const landingPage = new LandingPage(appManager, this.menuicons, fileManager, filePanel, contentImport)
this.settings = new SettingsTab(Registry.getInstance().get('config').api, editor, appManager)
this.engine.register([
this.menuicons,
landingPage,
this.hiddenPanel,
this.sidePanel,
filePanel,
pluginManagerComponent,
this.settings
])
this.engine.register([this.menuicons, landingPage, this.hiddenPanel, this.sidePanel, filePanel, pluginManagerComponent, this.settings])
// CONTENT VIEWS & DEFAULT PLUGINS
const openZeppelinProxy = new OpenZeppelinProxy(blockchain)
const linkLibraries = new LinkLibraries(blockchain)
const deployLibraries = new DeployLibraries(blockchain)
const compileTab = new CompileTab(
Registry.getInstance().get('config').api,
Registry.getInstance().get('filemanager').api
)
const compileTab = new CompileTab(Registry.getInstance().get('config').api, Registry.getInstance().get('filemanager').api)
const run = new RunTab(
blockchain,
Registry.getInstance().get('config').api,
@ -411,27 +381,44 @@ class AppComponent {
await this.appManager.activatePlugin(['layout'])
await this.appManager.activatePlugin(['notification'])
await this.appManager.activatePlugin(['editor'])
await this.appManager.activatePlugin(['permissionhandler', 'theme', 'locale', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter'])
await this.appManager.activatePlugin([
'permissionhandler',
'theme',
'locale',
'fileManager',
'compilerMetadata',
'compilerArtefacts',
'network',
'web3Provider',
'offsetToLineColumnConverter'
])
await this.appManager.activatePlugin(['mainPanel', 'menuicons', 'tabs'])
await this.appManager.activatePlugin(['sidePanel']) // activating host plugin separately
await this.appManager.activatePlugin(['home'])
await this.appManager.activatePlugin(['settings', 'config'])
await this.appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'codeParser', 'codeFormatter', 'fileDecorator', 'terminal', 'blockchain', 'fetchAndCompile', 'contentImport', 'gistHandler'])
await this.appManager.activatePlugin([
'hiddenPanel',
'pluginManager',
'codeParser',
'codeFormatter',
'fileDecorator',
'terminal',
'blockchain',
'fetchAndCompile',
'contentImport',
'gistHandler'
])
await this.appManager.activatePlugin(['settings'])
await this.appManager.activatePlugin(['walkthrough', 'storage', 'search', 'compileAndRun', 'recorder'])
await this.appManager.activatePlugin(['solidity-script'])
this.appManager.on(
'filePanel',
'workspaceInitializationCompleted',
async () => {
this.appManager.on('filePanel', 'workspaceInitializationCompleted', async () => {
// for e2e tests
const loadedElement = document.createElement('span')
loadedElement.setAttribute('data-id', 'workspaceloaded')
document.body.appendChild(loadedElement)
await this.appManager.registerContextMenuItems()
}
)
})
await this.appManager.activatePlugin(['filePanel'])
// Set workspace after initial activation
@ -442,9 +429,7 @@ class AppComponent {
.then(async () => {
try {
if (params.deactivate) {
await this.appManager.deactivatePlugin(
params.deactivate.split(',')
)
await this.appManager.deactivatePlugin(params.deactivate.split(','))
}
} catch (e) {
console.log(e)
@ -454,10 +439,7 @@ class AppComponent {
this.menuicons.select('solidity')
} else {
// If plugins are loaded from the URL params, we focus on the last one.
if (
this.appManager.pluginLoader.current === 'queryParams' &&
this.workspace.length > 0
) {
if (this.appManager.pluginLoader.current === 'queryParams' && this.workspace.length > 0) {
this.menuicons.select(this.workspace[this.workspace.length - 1])
} else {
this.appManager.call('tabs', 'focus', 'home')
@ -474,17 +456,13 @@ class AppComponent {
}
if (params.calls) {
const calls = params.calls.split("///");
const calls = params.calls.split('///')
// call all functions in the list, one after the other
for (const call of calls) {
const callDetails = call.split("//");
const callDetails = call.split('//')
if (callDetails.length > 1) {
this.appManager.call(
"notification",
"toast",
`initiating ${callDetails[0]} and calling "${callDetails[1]}" ...`
);
this.appManager.call('notification', 'toast', `initiating ${callDetails[0]} and calling "${callDetails[1]}" ...`)
// @todo(remove the timeout when activatePlugin is on 0.3.0)
try {

@ -1,5 +1,5 @@
import * as packageJson from '../../../../../package.json'
import {InjectedL2Provider} from './injected-L2-provider'
import {InjectedCustomProvider} from './injected-custom-provider'
const profile = {
name: 'injected-arbitrum-one-provider',
@ -10,7 +10,7 @@ const profile = {
version: packageJson.version
}
export class InjectedArbitrumOneProvider extends InjectedL2Provider {
export class InjectedArbitrumOneProvider extends InjectedCustomProvider {
constructor() {
super(profile, 'Arbitrum One', '0xa4b1', ['https://arb1.arbitrum.io/rpc'])
}

@ -1,6 +1,6 @@
import {InjectedProviderDefaultBase} from './injected-provider-default'
export class InjectedL2Provider extends InjectedProviderDefaultBase {
export class InjectedCustomProvider extends InjectedProviderDefaultBase {
chainName: string
chainId: string
rpcUrls: Array<string>
@ -14,13 +14,13 @@ export class InjectedL2Provider extends InjectedProviderDefaultBase {
async init() {
await super.init()
if (this.chainName && this.rpcUrls && this.rpcUrls.length > 0) await addL2Network(this.chainName, this.chainId, this.rpcUrls)
else throw new Error('Cannot add the L2 network to main injected provider')
if (this.chainName && this.rpcUrls && this.rpcUrls.length > 0) await addCustomNetwork(this.chainName, this.chainId, this.rpcUrls)
else throw new Error('Cannot add the custom network to main injected provider')
return {}
}
}
export const addL2Network = async (chainName: string, chainId: string, rpcUrls: Array<string>) => {
export const addCustomNetwork = async (chainName: string, chainId: string, rpcUrls: Array<string>) => {
try {
await (window as any).ethereum.request({
method: 'wallet_switchEthereumChain',

@ -0,0 +1,17 @@
import * as packageJson from '../../../../../package.json'
import {InjectedCustomProvider} from './injected-custom-provider'
const profile = {
name: 'injected-ephemery-testnet-provider',
displayName: 'Injected Ephemery Testnet Provider',
kind: 'provider',
description: 'Injected Ephemery Testnet Provider',
methods: ['sendAsync', 'init'],
version: packageJson.version
}
export class InjectedEphemeryTestnetProvider extends InjectedCustomProvider {
constructor() {
super(profile, 'Ephemery Testnet', '0x259C709', ['https://otter.bordel.wtf/erigon', 'https://eth.ephemeral.zeus.fyi'])
}
}

@ -1,5 +1,5 @@
import * as packageJson from '../../../../../package.json'
import {InjectedL2Provider} from './injected-L2-provider'
import {InjectedCustomProvider} from './injected-custom-provider'
const profile = {
name: 'injected-optimism-provider',
@ -10,7 +10,7 @@ const profile = {
version: packageJson.version
}
export class Injected0ptimismProvider extends InjectedL2Provider {
export class Injected0ptimismProvider extends InjectedCustomProvider {
constructor() {
super(profile, 'Optimism', '0xa', ['https://mainnet.optimism.io'])
}

@ -6,7 +6,7 @@ import * as packageJson from '../../../../../package.json'
const EventManager = require('../../lib/events')
const Recorder = require('../tabs/runTab/model/recorder.js')
const _paq = window._paq = window._paq || []
const _paq = (window._paq = window._paq || [])
const profile = {
name: 'udapp',
@ -20,7 +20,17 @@ const profile = {
maintainedBy: 'Remix',
permission: true,
events: ['newTransaction'],
methods: ['createVMAccount', 'sendTransaction', 'getAccounts', 'pendingTransactionsCount', 'getSettings', 'setEnvironmentMode', 'clearAllInstances', 'addInstance', 'resolveContractAndAddInstance']
methods: [
'createVMAccount',
'sendTransaction',
'getAccounts',
'pendingTransactionsCount',
'getSettings',
'setEnvironmentMode',
'clearAllInstances',
'addInstance',
'resolveContractAndAddInstance'
]
}
export class RunTab extends ViewPlugin {
@ -91,7 +101,11 @@ export class RunTab extends ViewPlugin {
}
render() {
return <div><RunTabUI plugin={this} /></div>
return (
<div>
<RunTabUI plugin={this} />
</div>
)
}
onReady(api) {
@ -134,10 +148,17 @@ export class RunTab extends ViewPlugin {
// basic injected
// if it's the trust wallet provider, we have a specific provider for that, see below
if (window && window.ethereum && !(window.ethereum.isTrustWallet || window.ethereum.selectedProvider?.isTrustWallet)) {
const displayNameInjected = `Injected Provider${(window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)) ?
window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet ? ' - Coinbase' :
window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet ? ' - Brave' :
window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask ? ' - MetaMask' : '' : ''}`
const displayNameInjected = `Injected Provider${
window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)
? window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet
? ' - Coinbase'
: window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet
? ' - Brave'
: window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask
? ' - MetaMask'
: ''
: ''
}`
await addProvider('injected', displayNameInjected, true, false)
} else if (window && !window.ethereum) {
// we still add "injected" if there's no provider (just so it's visible to the user).
@ -163,6 +184,9 @@ export class RunTab extends ViewPlugin {
// wallet connect
await addProvider('walletconnect', 'WalletConnect', false, false)
// testnet
await addProvider('injected-ephemery-testnet-provider', 'Ephemery Testnet', true, false)
// external provider
await addProvider('basic-http-provider', 'Custom - External Http Provider', false, false)
await addProvider('hardhat-provider', 'Dev - Hardhat Provider', false, false)

@ -2,34 +2,115 @@ import { PluginManager } from '@remixproject/engine'
import {EventEmitter} from 'events'
import {QueryParams} from '@remix-project/remix-lib'
import {IframePlugin} from '@remixproject/engine-web'
const _paq = window._paq = window._paq || []
const _paq = (window._paq = window._paq || [])
// requiredModule removes the plugin from the plugin manager list on UI
const requiredModules = [ // services + layout views + system views
'manager', 'config', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme', 'locale',
'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons',
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout',
'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy',
'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected', 'injected-trustwallet', 'injected-optimism-provider', 'injected-arbitrum-one-provider', 'vm-custom-fork', 'vm-goerli-fork', 'vm-mainnet-fork', 'vm-sepolia-fork', 'vm-merge', 'vm-london', 'vm-berlin',
const requiredModules = [
// services + layout views + system views
'manager',
'config',
'compilerArtefacts',
'compilerMetadata',
'contextualListener',
'editor',
'offsetToLineColumnConverter',
'network',
'theme',
'locale',
'fileManager',
'contentImport',
'blockchain',
'web3Provider',
'scriptRunner',
'fetchAndCompile',
'mainPanel',
'hiddenPanel',
'sidePanel',
'menuicons',
'filePanel',
'terminal',
'settings',
'pluginManager',
'tabs',
'udapp',
'dGitProvider',
'solidity',
'solidity-logic',
'gistHandler',
'layout',
'notification',
'permissionhandler',
'walkthrough',
'storage',
'restorebackupzip',
'link-libraries',
'deploy-libraries',
'openzeppelin-proxy',
'hardhat-provider',
'ganache-provider',
'foundry-provider',
'basic-http-provider',
'injected',
'injected-trustwallet',
'injected-optimism-provider',
'injected-arbitrum-one-provider',
'injected-ephemery-testnet-provider',
'vm-custom-fork',
'vm-goerli-fork',
'vm-mainnet-fork',
'vm-sepolia-fork',
'vm-merge',
'vm-london',
'vm-berlin',
'vm-shanghai',
'compileAndRun', 'search', 'recorder', 'fileDecorator', 'codeParser', 'codeFormatter', 'solidityumlgen', 'contractflattener', 'solidity-script']
'compileAndRun',
'search',
'recorder',
'fileDecorator',
'codeParser',
'codeFormatter',
'solidityumlgen',
'contractflattener',
'solidity-script'
]
// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)
const dependentModules = ['foundry', 'hardhat', 'truffle', 'slither']
const loadLocalPlugins = ["doc-gen", "doc-viewer", "etherscan", "vyper", "solhint", "walletconnect", "circuit-compiler"]
const loadLocalPlugins = ['doc-gen', 'doc-viewer', 'etherscan', 'vyper', 'solhint', 'walletconnect', 'circuit-compiler']
const sensitiveCalls = {
'fileManager': ['writeFile', 'copyFile', 'rename', 'copyDir'],
'contentImport': ['resolveAndSave'],
'web3Provider': ['sendAsync'],
fileManager: ['writeFile', 'copyFile', 'rename', 'copyDir'],
contentImport: ['resolveAndSave'],
web3Provider: ['sendAsync']
}
export function isNative(name) {
// nativePlugin allows to bypass the permission request
const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'solidity-logic', 'solidityStaticAnalysis', 'solidityUnitTesting',
'layout', 'notification', 'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected-optimism-provider',
'tabs', 'injected-arbitrum-one-provider', 'injected', 'doc-gen', 'doc-viewer']
const nativePlugins = [
'vyper',
'workshops',
'debugger',
'remixd',
'menuicons',
'solidity',
'solidity-logic',
'solidityStaticAnalysis',
'solidityUnitTesting',
'layout',
'notification',
'hardhat-provider',
'ganache-provider',
'foundry-provider',
'basic-http-provider',
'injected-optimism-provider',
'tabs',
'injected-arbitrum-one-provider',
'injected-ephemery-testnet-provider',
'injected',
'doc-gen',
'doc-viewer'
]
return nativePlugins.includes(name) || requiredModules.includes(name)
}
@ -44,9 +125,7 @@ export function isNative(name) {
* @returns {boolean}
*/
export function canActivate(from, to) {
return ['ethdoc'].includes(from.name) ||
isNative(from.name) ||
(to && from && from.canActivate && from.canActivate.includes(to.name))
return ['ethdoc'].includes(from.name) || isNative(from.name) || (to && from && from.canActivate && from.canActivate.includes(to.name))
}
export class RemixAppManager extends PluginManager {
@ -72,10 +151,7 @@ export class RemixAppManager extends PluginManager {
async deactivatePlugin(name) {
const profile = await this.getProfile(name)
const [to, from] = [
profile,
await this.getProfile(this.requestFrom)
]
const [to, from] = [profile, await this.getProfile(this.requestFrom)]
if (this.canDeactivatePlugin(from, to)) {
if (profile.methods.includes('deactivate')) {
try {
@ -104,7 +180,10 @@ export class RemixAppManager extends PluginManager {
}
onPluginActivated(plugin) {
this.pluginLoader.set(plugin, this.actives.filter((plugin) => !this.isDependent(plugin)))
this.pluginLoader.set(
plugin,
this.actives.filter((plugin) => !this.isDependent(plugin))
)
this.event.emit('activate', plugin)
this.emit('activate', plugin)
if (!requiredModules.includes(plugin.name)) _paq.push(['trackEvent', 'pluginManager', 'activate', plugin.name])
@ -121,7 +200,10 @@ export class RemixAppManager extends PluginManager {
}
onPluginDeactivated(plugin) {
this.pluginLoader.set(plugin, this.actives.filter((plugin) => !this.isDependent(plugin)))
this.pluginLoader.set(
plugin,
this.actives.filter((plugin) => !this.isDependent(plugin))
)
this.event.emit('deactivate', plugin)
_paq.push(['trackEvent', 'pluginManager', 'deactivate', plugin.name])
}
@ -142,7 +224,7 @@ export class RemixAppManager extends PluginManager {
plugins = await res.json()
plugins = plugins.filter((plugin) => {
if (plugin.targets && Array.isArray(plugin.targets) && plugin.targets.length > 0) {
return (plugin.targets.includes('remix'))
return plugin.targets.includes('remix')
}
return true
})
@ -177,7 +259,7 @@ export class RemixAppManager extends PluginManager {
}
}
return plugins.map(plugin => {
return plugins.map((plugin) => {
if (plugin.name === testPluginName) plugin.url = testPluginUrl
return new IframePlugin(plugin)
})
@ -249,11 +331,15 @@ class PluginLoader {
const saved = actives.filter((name) => !this.donotAutoReload.includes(name))
localStorage.setItem('workspace', JSON.stringify(saved))
},
get: () => { return JSON.parse(localStorage.getItem('workspace')) }
get: () => {
return JSON.parse(localStorage.getItem('workspace'))
}
}
this.loaders.queryParams = {
set: () => { /* Do nothing. */ },
set: () => {
/* Do nothing. */
},
get: () => {
const {activate} = queryParams.get()
if (!activate) return []

Loading…
Cancel
Save