add ephemery provider

add_ephemery_provider
yann300 1 year ago
parent 60f93d7e13
commit 5ba9cca2ec
  1. 211
      apps/remix-ide/src/app.js
  2. 20
      apps/remix-ide/src/app/providers/injected-ephemery-testnet-provider.tsx
  3. 269
      apps/remix-ide/src/app/udapp/run-tab.js
  4. 194
      apps/remix-ide/src/remixAppManager.js

@ -1,57 +1,74 @@
'use strict'
import { RunTab, makeUdapp } from './app/udapp'
import { RemixEngine } from './remixEngine'
import { RemixAppManager } from './remixAppManager'
import { ThemeModule } from './app/tabs/theme-module'
import { LocaleModule } from './app/tabs/locale-module'
import { NetworkModule } from './app/tabs/network-module'
import { Web3ProviderModule } from './app/tabs/web3-provider'
import { CompileAndRun } from './app/tabs/compile-and-run'
import { SidePanel } from './app/components/side-panel'
import { HiddenPanel } from './app/components/hidden-panel'
import { VerticalIcons } from './app/components/vertical-icons'
import { LandingPage } from './app/ui/landing-page/landing-page'
import { MainPanel } from './app/components/main-panel'
import { PermissionHandlerPlugin } from './app/plugins/permission-handler-plugin'
import { AstWalker } from '@remix-project/remix-astwalker'
import { LinkLibraries, DeployLibraries, OpenZeppelinProxy } from '@remix-project/core-plugin'
import { CodeParser } from './app/plugins/parser/code-parser'
import { SolidityScript } from './app/plugins/solidity-script'
import { WalkthroughService } from './walkthroughService'
import { OffsetToLineColumnConverter, CompilerMetadata, CompilerArtefacts, FetchAndCompile, CompilerImports, GistHandler } from '@remix-project/core-plugin'
import {RunTab, makeUdapp} from './app/udapp'
import {RemixEngine} from './remixEngine'
import {RemixAppManager} from './remixAppManager'
import {ThemeModule} from './app/tabs/theme-module'
import {LocaleModule} from './app/tabs/locale-module'
import {NetworkModule} from './app/tabs/network-module'
import {Web3ProviderModule} from './app/tabs/web3-provider'
import {CompileAndRun} from './app/tabs/compile-and-run'
import {SidePanel} from './app/components/side-panel'
import {HiddenPanel} from './app/components/hidden-panel'
import {VerticalIcons} from './app/components/vertical-icons'
import {LandingPage} from './app/ui/landing-page/landing-page'
import {MainPanel} from './app/components/main-panel'
import {PermissionHandlerPlugin} from './app/plugins/permission-handler-plugin'
import {AstWalker} from '@remix-project/remix-astwalker'
import {
LinkLibraries,
DeployLibraries,
OpenZeppelinProxy
} from '@remix-project/core-plugin'
import {CodeParser} from './app/plugins/parser/code-parser'
import {SolidityScript} from './app/plugins/solidity-script'
import {WalkthroughService} from './walkthroughService'
import {
OffsetToLineColumnConverter,
CompilerMetadata,
CompilerArtefacts,
FetchAndCompile,
CompilerImports,
GistHandler
} from '@remix-project/core-plugin'
import Registry from './app/state/registry'
import { ConfigPlugin } from './app/plugins/config'
import { StoragePlugin } from './app/plugins/storage'
import { Layout } from './app/panels/layout'
import { NotificationPlugin } from './app/plugins/notification'
import { Blockchain } from './blockchain/blockchain'
import { MergeVMProvider, LondonVMProvider, BerlinVMProvider, ShanghaiVMProvider } from './app/providers/vm-provider'
import { MainnetForkVMProvider } from './app/providers/mainnet-vm-fork-provider'
import { SepoliaForkVMProvider } from './app/providers/sepolia-vm-fork-provider'
import { GoerliForkVMProvider } from './app/providers/goerli-vm-fork-provider'
import { CustomForkVMProvider } from './app/providers/custom-vm-fork-provider'
import { HardhatProvider } from './app/providers/hardhat-provider'
import { GanacheProvider } from './app/providers/ganache-provider'
import { FoundryProvider } from './app/providers/foundry-provider'
import { ExternalHttpProvider } from './app/providers/external-http-provider'
import { InjectedProviderDefault } from './app/providers/injected-provider-default'
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 { FileDecorator } from './app/plugins/file-decorator'
import { CodeFormat } from './app/plugins/code-format'
import { SolidityUmlGen } from './app/plugins/solidity-umlgen'
import { ContractFlattener } from './app/plugins/contractFlattener'
import {ConfigPlugin} from './app/plugins/config'
import {StoragePlugin} from './app/plugins/storage'
import {Layout} from './app/panels/layout'
import {NotificationPlugin} from './app/plugins/notification'
import {Blockchain} from './blockchain/blockchain'
import {
MergeVMProvider,
LondonVMProvider,
BerlinVMProvider,
ShanghaiVMProvider
} from './app/providers/vm-provider'
import {MainnetForkVMProvider} from './app/providers/mainnet-vm-fork-provider'
import {SepoliaForkVMProvider} from './app/providers/sepolia-vm-fork-provider'
import {GoerliForkVMProvider} from './app/providers/goerli-vm-fork-provider'
import {CustomForkVMProvider} from './app/providers/custom-vm-fork-provider'
import {HardhatProvider} from './app/providers/hardhat-provider'
import {GanacheProvider} from './app/providers/ganache-provider'
import {FoundryProvider} from './app/providers/foundry-provider'
import {ExternalHttpProvider} from './app/providers/external-http-provider'
import {InjectedProviderDefault} from './app/providers/injected-provider-default'
import {InjectedProviderTrustWallet} from './app/providers/injected-provider-trustwallet'
import {Injected0ptimismProvider} from './app/providers/injected-optimism-provider'
import {InjectedEphemeryTestnetProvider} from './app/providers/injected-ephemery-testnet-provider'
import {InjectedArbitrumOneProvider} from './app/providers/injected-arbitrum-one-provider'
import {FileDecorator} from './app/plugins/file-decorator'
import {CodeFormat} from './app/plugins/code-format'
import {SolidityUmlGen} from './app/plugins/solidity-umlgen'
import {ContractFlattener} from './app/plugins/contractFlattener'
const isElectron = require('is-electron')
const remixLib = require('@remix-project/remix-lib')
import { QueryParams } from '@remix-project/remix-lib'
import { SearchPlugin } from './app/tabs/search'
import {QueryParams} from '@remix-project/remix-lib'
import {SearchPlugin} from './app/tabs/search'
const Storage = remixLib.Storage
const RemixDProvider = require('./app/files/remixDProvider')
@ -67,12 +84,12 @@ const PluginManagerComponent = require('./app/components/plugin-manager-componen
const CompileTab = require('./app/tabs/compile-tab')
const SettingsTab = require('./app/tabs/settings-tab')
const AnalysisTab = require('./app/tabs/analysis-tab')
const { DebuggerTab } = require('./app/tabs/debugger-tab')
const {DebuggerTab} = require('./app/tabs/debugger-tab')
const TestTab = require('./app/tabs/test-tab')
const FilePanel = require('./app/panels/file-panel')
const Editor = require('./app/editor/editor')
const Terminal = require('./app/panels/terminal')
const { TabProxy } = require('./app/panels/tab-proxy.js')
const {TabProxy} = require('./app/panels/tab-proxy.js')
class AppComponent {
constructor() {
@ -84,7 +101,7 @@ class AppComponent {
// load app config
const config = new Config(configStorage)
Registry.getInstance().put({ api: config, name: 'config' })
Registry.getInstance().put({api: config, name: 'config'})
// load file system
this._components.filesProviders = {}
@ -119,7 +136,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,
@ -153,19 +170,19 @@ class AppComponent {
this.themeModule = new ThemeModule()
// ----------------- locale service ---------------------------------
this.localeModule = new LocaleModule()
Registry.getInstance().put({ api: this.themeModule, name: 'themeModule' })
Registry.getInstance().put({ api: this.localeModule, name: 'localeModule' })
Registry.getInstance().put({api: this.themeModule, name: 'themeModule'})
Registry.getInstance().put({api: this.localeModule, name: 'localeModule'})
// ----------------- editor service ----------------------------
const editor = new Editor() // wrapper around ace editor
Registry.getInstance().put({ api: editor, name: 'editor' })
Registry.getInstance().put({api: editor, name: 'editor'})
editor.event.register('requiringToSaveCurrentfile', () =>
fileManager.saveCurrentFile()
)
// ----------------- fileManager service ----------------------------
const fileManager = new FileManager(editor, appManager)
Registry.getInstance().put({ api: fileManager, name: 'filemanager' })
Registry.getInstance().put({api: fileManager, name: 'filemanager'})
// ----------------- dGit provider ---------------------------------
const dGitProvider = new DGitProvider()
@ -220,9 +237,11 @@ 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({
@ -232,11 +251,13 @@ 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 },
{appManager, blockchain},
{
getPosition: event => {
getPosition: (event) => {
const limitUp = 36
const limitDown = 20
const height = window.innerHeight
@ -298,6 +319,7 @@ class AppComponent {
trustWalletInjectedProvider,
injected0ptimismProvider,
injectedArbitrumOneProvider,
injectedEphemeryTestnetProvider,
this.walkthroughService,
search,
solidityumlgen,
@ -307,7 +329,7 @@ class AppComponent {
// LAYOUT & SYSTEM VIEWS
const appPanel = new MainPanel()
Registry.getInstance().put({ api: this.mainview, name: 'mainview' })
Registry.getInstance().put({api: this.mainview, name: 'mainview'})
const tabProxy = new TabProxy(fileManager, editor)
this.engine.register([appPanel, tabProxy])
@ -391,10 +413,10 @@ class AppComponent {
])
this.layout.panels = {
tabs: { plugin: tabProxy, active: true },
editor: { plugin: editor, active: true },
main: { plugin: appPanel, active: false },
terminal: { plugin: terminal, active: true, minimized: false }
tabs: {plugin: tabProxy, active: true},
editor: {plugin: editor, active: true},
main: {plugin: appPanel, active: false},
terminal: {plugin: terminal, active: true, minimized: false}
}
}
@ -410,14 +432,41 @@ 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([
'walkthrough',
'storage',
'search',
'compileAndRun',
'recorder'
])
await this.appManager.activatePlugin(['solidity-script'])
this.appManager.on(
@ -448,7 +497,11 @@ class AppComponent {
} catch (e) {
console.log(e)
}
if (params.code && (!params.activate || params.activate.split(',').includes('solidity'))) {
if (
params.code &&
(!params.activate ||
params.activate.split(',').includes('solidity'))
) {
// if code is given in url we focus on solidity plugin
this.menuicons.select('solidity')
} else {
@ -466,24 +519,28 @@ class AppComponent {
if (params.call) {
const callDetails = params.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)
await this.appManager.call(...callDetails).catch(console.error)
}
}
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",
'notification',
'toast',
`initiating ${callDetails[0]} and calling "${callDetails[1]}" ...`
);
)
// @todo(remove the timeout when activatePlugin is on 0.3.0)
try {
@ -503,7 +560,13 @@ class AppComponent {
})
// activate solidity plugin
this.appManager.activatePlugin(['solidity', 'udapp', 'deploy-libraries', 'link-libraries', 'openzeppelin-proxy'])
this.appManager.activatePlugin([
'solidity',
'udapp',
'deploy-libraries',
'link-libraries',
'openzeppelin-proxy'
])
}
}

@ -0,0 +1,20 @@
import * as packageJson from '../../../../../package.json'
import {InjectedL2Provider} from './injected-L2-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 InjectedL2Provider {
constructor() {
super(profile, 'Optimism', '0x259C709', [
'https://otter.bordel.wtf/erigon',
'https://eth.ephemeral.zeus.fyi'
])
}
}

@ -1,12 +1,12 @@
import React from 'react' // eslint-disable-line
import { RunTabUI } from '@remix-ui/run-tab'
import { ViewPlugin } from '@remixproject/engine-web'
import { addressToString } from '@remix-ui/helper'
import {RunTabUI} from '@remix-ui/run-tab'
import {ViewPlugin} from '@remixproject/engine-web'
import {addressToString} from '@remix-ui/helper'
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,11 +20,30 @@ 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 {
constructor (blockchain, config, fileManager, editor, filePanel, compilersArtefacts, networkModule, fileProvider) {
constructor(
blockchain,
config,
fileManager,
editor,
filePanel,
compilersArtefacts,
networkModule,
fileProvider
) {
super(profile)
this.event = new EventManager()
this.config = config
@ -41,13 +60,13 @@ export class RunTab extends ViewPlugin {
this.el = document.createElement('div')
}
setupEvents () {
setupEvents() {
this.blockchain.events.on('newTransaction', (tx, receipt) => {
this.emit('newTransaction', tx, receipt)
})
}
getSettings () {
getSettings() {
return new Promise((resolve, reject) => {
resolve({
selectedAccount: this.REACT_API.accounts.selectedAccount,
@ -57,51 +76,66 @@ export class RunTab extends ViewPlugin {
})
}
async setEnvironmentMode (env) {
const canCall = await this.askUserPermission('setEnvironmentMode', 'change the environment used')
async setEnvironmentMode(env) {
const canCall = await this.askUserPermission(
'setEnvironmentMode',
'change the environment used'
)
if (canCall) {
env = typeof env === 'string' ? { context: env } : env
env = typeof env === 'string' ? {context: env} : env
this.emit('setEnvironmentModeReducer', env, this.currentRequest.from)
}
}
clearAllInstances () {
clearAllInstances() {
this.emit('clearAllInstancesReducer')
}
addInstance (address, abi, name) {
addInstance(address, abi, name) {
this.emit('addInstanceReducer', address, abi, name)
}
createVMAccount (newAccount) {
createVMAccount(newAccount) {
return this.blockchain.createVMAccount(newAccount)
}
sendTransaction (tx) {
sendTransaction(tx) {
_paq.push(['trackEvent', 'udapp', 'sendTx', 'udappTransaction'])
return this.blockchain.sendTransaction(tx)
}
getAccounts (cb) {
getAccounts(cb) {
return this.blockchain.getAccounts(cb)
}
pendingTransactionsCount () {
pendingTransactionsCount() {
return this.blockchain.pendingTransactionsCount()
}
render () {
return <div><RunTabUI plugin={this} /></div>
render() {
return (
<div>
<RunTabUI plugin={this} />
</div>
)
}
onReady (api) {
onReady(api) {
this.REACT_API = api
}
async onInitDone () {
async onInitDone() {
const udapp = this // eslint-disable-line
const addProvider = async (name, displayName, isInjected, isVM, fork = '', dataId = '', title = '') => {
const addProvider = async (
name,
displayName,
isInjected,
isVM,
fork = '',
dataId = '',
title = ''
) => {
await this.call('blockchain', 'addProvider', {
options: {},
dataId,
@ -113,13 +147,13 @@ export class RunTab extends ViewPlugin {
title,
init: async function () {
const options = await udapp.call(name, 'init')
if (options) {
if (options) {
this.options = options
if (options['fork']) this.fork = options['fork']
}
},
provider: {
async sendAsync (payload, callback) {
async sendAsync(payload, callback) {
try {
const result = await udapp.call(name, 'sendAsync', payload)
callback(null, result)
@ -133,11 +167,30 @@ 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' : '' : ''}`
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'
: ''
: ''
}`
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).
@ -145,45 +198,155 @@ export class RunTab extends ViewPlugin {
}
if (window && window.trustwallet) {
const displayNameInjected = `Injected Provider - TrustWallet`
await addProvider('injected-trustwallet', displayNameInjected, true, false)
const displayNameInjected = `Injected Provider - TrustWallet`
await addProvider(
'injected-trustwallet',
displayNameInjected,
true,
false
)
}
// VM
const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.'
await addProvider('vm-shanghai', 'Remix VM (Shanghai)', false, true, 'shanghai', 'settingsVMShanghaiMode', titleVM)
await addProvider('vm-merge', 'Remix VM (Merge)', false, true, 'merge', 'settingsVMMergeMode', titleVM)
await addProvider('vm-london', 'Remix VM (London)', false, true, 'london', 'settingsVMLondonMode', titleVM)
await addProvider('vm-berlin', 'Remix VM (Berlin)', false, true, 'berlin', 'settingsVMBerlinMode', titleVM)
await addProvider('vm-mainnet-fork', 'Remix VM - Mainnet fork', false, true, 'merge', 'settingsVMMainnetMode', titleVM)
await addProvider('vm-sepolia-fork', 'Remix VM - Sepolia fork', false, true, 'merge', 'settingsVMSepoliaMode', titleVM)
await addProvider('vm-goerli-fork', 'Remix VM - Goerli fork', false, true, 'merge', 'settingsVMGoerliMode', titleVM)
await addProvider('vm-custom-fork', 'Remix VM - Custom fork', false, true, '', 'settingsVMCustomMode', titleVM)
const titleVM =
'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.'
await addProvider(
'vm-shanghai',
'Remix VM (Shanghai)',
false,
true,
'shanghai',
'settingsVMShanghaiMode',
titleVM
)
await addProvider(
'vm-merge',
'Remix VM (Merge)',
false,
true,
'merge',
'settingsVMMergeMode',
titleVM
)
await addProvider(
'vm-london',
'Remix VM (London)',
false,
true,
'london',
'settingsVMLondonMode',
titleVM
)
await addProvider(
'vm-berlin',
'Remix VM (Berlin)',
false,
true,
'berlin',
'settingsVMBerlinMode',
titleVM
)
await addProvider(
'vm-mainnet-fork',
'Remix VM - Mainnet fork',
false,
true,
'merge',
'settingsVMMainnetMode',
titleVM
)
await addProvider(
'vm-sepolia-fork',
'Remix VM - Sepolia fork',
false,
true,
'merge',
'settingsVMSepoliaMode',
titleVM
)
await addProvider(
'vm-goerli-fork',
'Remix VM - Goerli fork',
false,
true,
'merge',
'settingsVMGoerliMode',
titleVM
)
await addProvider(
'vm-custom-fork',
'Remix VM - Custom fork',
false,
true,
'',
'settingsVMCustomMode',
titleVM
)
// 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)
await addProvider('ganache-provider', 'Dev - Ganache Provider', false, false)
await addProvider('foundry-provider', 'Dev - Foundry Provider', false, false)
// injected provider
await addProvider('injected-optimism-provider', 'L2 - Optimism Provider', true, false)
await addProvider('injected-arbitrum-one-provider', 'L2 - Arbitrum One Provider', true, false)
await addProvider(
'basic-http-provider',
'Custom - External Http Provider',
false,
false
)
await addProvider(
'hardhat-provider',
'Dev - Hardhat Provider',
false,
false
)
await addProvider(
'ganache-provider',
'Dev - Ganache Provider',
false,
false
)
await addProvider(
'foundry-provider',
'Dev - Foundry Provider',
false,
false
)
// injected provider
await addProvider(
'injected-optimism-provider',
'L2 - Optimism Provider',
true,
false
)
await addProvider(
'injected-arbitrum-one-provider',
'L2 - Arbitrum One Provider',
true,
false
)
}
writeFile (fileName, content) {
writeFile(fileName, content) {
return this.call('fileManager', 'writeFile', fileName, content)
}
readFile (fileName) {
readFile(fileName) {
return this.call('fileManager', 'readFile', fileName)
}
async resolveContractAndAddInstance (contractObject, address) {
const data = await this.compilersArtefacts.getCompilerAbstract(contractObject.contract.file)
async resolveContractAndAddInstance(contractObject, address) {
const data = await this.compilersArtefacts.getCompilerAbstract(
contractObject.contract.file
)
this.compilersArtefacts.addResolvedContract(addressToString(address), data)
this.addInstance(address, contractObject.abi, contractObject.name)

@ -1,35 +1,123 @@
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 || []
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 || [])
// 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-ephemery-testnet-provider',
'injected-arbitrum-one-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']
const loadLocalPlugins = [
'doc-gen',
'doc-viewer',
'etherscan',
'vyper',
'solhint',
'walletconnect'
]
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',
'injected-ephemery-testnet-provider',
'tabs',
'injected-arbitrum-one-provider',
'injected',
'doc-gen',
'doc-viewer'
]
return nativePlugins.includes(name) || requiredModules.includes(name)
}
@ -44,16 +132,19 @@ export function isNative(name) {
* @returns {boolean}
*/
export function canActivate(from, to) {
return ['ethdoc'].includes(from.name) ||
return (
['ethdoc'].includes(from.name) ||
isNative(from.name) ||
(to && from && from.canActivate && from.canActivate.includes(to.name))
)
}
export class RemixAppManager extends PluginManager {
constructor() {
super()
this.event = new EventEmitter()
this.pluginsDirectory = 'https://raw.githubusercontent.com/ethereum/remix-plugins-directory/master/build/metadata.json'
this.pluginsDirectory =
'https://raw.githubusercontent.com/ethereum/remix-plugins-directory/master/build/metadata.json'
this.pluginLoader = new PluginLoader()
}
@ -72,10 +163,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 {
@ -89,7 +177,8 @@ export class RemixAppManager extends PluginManager {
}
async canCall(from, to, method, message) {
const isSensitiveCall = sensitiveCalls[to] && sensitiveCalls[to].includes(method)
const isSensitiveCall =
sensitiveCalls[to] && sensitiveCalls[to].includes(method)
// Make sure the caller of this methods is the target plugin
if (to !== this.currentRequest.from) {
return false
@ -100,14 +189,26 @@ export class RemixAppManager extends PluginManager {
}
// ask the user for permission
return await this.call('permissionhandler', 'askPermission', this.profiles[from], this.profiles[to], method, message, isSensitiveCall)
return await this.call(
'permissionhandler',
'askPermission',
this.profiles[from],
this.profiles[to],
method,
message,
isSensitiveCall
)
}
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])
if (!requiredModules.includes(plugin.name))
_paq.push(['trackEvent', 'pluginManager', 'activate', plugin.name])
}
getAll() {
@ -121,7 +222,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])
}
@ -141,8 +245,12 @@ export class RemixAppManager extends PluginManager {
const res = await fetch(this.pluginsDirectory)
plugins = await res.json()
plugins = plugins.filter((plugin) => {
if (plugin.targets && Array.isArray(plugin.targets) && plugin.targets.length > 0) {
return (plugin.targets.includes('remix'))
if (
plugin.targets &&
Array.isArray(plugin.targets) &&
plugin.targets.length > 0
) {
return plugin.targets.includes('remix')
}
return true
})
@ -167,7 +275,11 @@ export class RemixAppManager extends PluginManager {
const profile = await fetch(`plugins/${plugin}/profile.json`)
const profileJson = await profile.json()
// remove duplicates
plugins = plugins.filter((p) => p.name !== profileJson.name && p.displayName !== profileJson.displayName)
plugins = plugins.filter(
(p) =>
p.name !== profileJson.name &&
p.displayName !== profileJson.displayName
)
// change url
profileJson.url = `plugins/${plugin}/index.html`
// add the local plugin
@ -177,7 +289,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)
})
@ -246,16 +358,22 @@ class PluginLoader {
this.loaders = {}
this.loaders.localStorage = {
set: (plugin, actives) => {
const saved = actives.filter((name) => !this.donotAutoReload.includes(name))
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()
const {activate} = queryParams.get()
if (!activate) return []
return activate.split(',')
}

Loading…
Cancel
Save