add grid view providers

pull/5003/head
yann300 7 months ago committed by Aniket
parent 9237095434
commit 40e3f7312f
  1. 4
      apps/remix-ide/src/app.js
  2. 153
      apps/remix-ide/src/app/providers/grid-providers.tsx
  3. 53
      apps/remix-ide/src/blockchain/blockchain.tsx
  4. 5
      apps/remix-ide/src/blockchain/execution-context.js
  5. 4
      libs/remix-ui/run-tab/src/lib/actions/events.ts
  6. 11
      libs/remix-ui/run-tab/src/lib/components/environment.tsx

@ -40,6 +40,7 @@ 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 { GridProviders } from './app/providers/grid-providers'
import { FileDecorator } from './app/plugins/file-decorator'
import { CodeFormat } from './app/plugins/code-format'
import { SolidityUmlGen } from './app/plugins/solidity-umlgen'
@ -276,6 +277,8 @@ class AppComponent {
const ganacheProvider = new GanacheProvider(blockchain)
const foundryProvider = new FoundryProvider(blockchain)
const externalHttpProvider = new ExternalHttpProvider(blockchain)
const gridProviders = new GridProviders()
// ----------------- convert offset to line/column service -----------
const offsetToLineColumnConverter = new OffsetToLineColumnConverter()
Registry.getInstance().put({
@ -350,6 +353,7 @@ class AppComponent {
ganacheProvider,
foundryProvider,
externalHttpProvider,
gridProviders,
this.walkthroughService,
search,
solidityumlgen,

@ -0,0 +1,153 @@
import React from 'react' // eslint-disable-line
import { ViewPlugin } from '@remixproject/engine-web'
import { PluginViewWrapper } from '@remix-ui/helper'
import { RemixUIGridView } from '@remix-ui/remix-ui-grid-view'
import { RemixUIGridSection } from '@remix-ui/remix-ui-grid-section'
import { RemixUIGridCell } from '@remix-ui/remix-ui-grid-cell'
import type { Provider } from '../../blockchain/blockchain'
import * as packageJson from '../../../../../package.json'
const _paq = (window._paq = window._paq || [])
const profile = {
name: 'gridProviders',
displayName: 'Grid providers',
icon: 'assets/img/deployAndRun.webp',
description: 'Pin web3 providers',
location: 'mainPanel',
documentation: 'https://remix-ide.readthedocs.io/en/latest/run.html',
version: packageJson.version,
maintainedBy: 'Remix',
permission: true,
events: [],
methods: []
}
type ProvidersSection = `Injected` | 'Remix VMs' | 'Externals'
export class GridProviders extends ViewPlugin {
providers: { [key in ProvidersSection]: Provider[] }
providersFlat: { [key: string]: Provider }
pinnedProviders: string[]
dispatch: React.Dispatch<any> = () => {}
constructor() {
super(profile)
this.providersFlat = {}
this.providers = {
'Injected': [],
'Remix VMs': [],
'Externals': []
}
}
async onActivation(): Promise<void> {
this.providersFlat = await this.call('blockchain', 'getAllProviders')
this.pinnedProviders = await this.call('blockchain', 'getPinnedProviders')
this.renderComponent()
}
addProvider (provider: Provider) {
if (provider.isInjected) {
this.providers['Injected'].push(provider)
} else if (provider.isVM) {
this.providers['Remix VMs'].push(provider)
} else {
this.providers['Externals'].push(provider)
}
}
setDispatch(dispatch: React.Dispatch<any>): void {
this.dispatch = dispatch
this.renderComponent()
}
render() {
return (
<div className="bg-dark" id="gridproviders">
<PluginViewWrapper plugin={this} />
</div>
)
}
renderComponent() {
this.dispatch({
...this
})
}
updateComponent(state: any) {
this.providers = {
'Injected': [],
'Remix VMs': [],
'Externals': []
}
console.log(this.providersFlat)
for (const [key, provider] of Object.entries(this.providersFlat)) {
this.addProvider(provider)
}
return (
<RemixUIGridView
plugin={this}
styleList={""}
logo='/assets/img/YouTubeLogo.webp'
enableFilter={true}
showUntagged={true}
showPin={true}
title='Select a Web3 provider'
description="Choose how you would like to interact with a chain."
>
<RemixUIGridSection
plugin={this}
title='Injected'
hScrollable= {true}
>
{this.providers['Injected'].map(provider => {
return <RemixUIGridCell
plugin={this}
title={provider.name}
pinned={this.pinnedProviders.includes(provider.name)}
pinStateCallback={(pinned: boolean) => {
this.emit(pinned ? 'providerPinned' : 'providerUnpinned', provider.name, provider)}
}
>
<div>{provider.name}</div>
</RemixUIGridCell>
})}
</RemixUIGridSection>
<RemixUIGridSection
plugin={this}
title='Remix VMs'
hScrollable= {true}
>{this.providers['Remix VMs'].map(provider => {
return <RemixUIGridCell
plugin={this}
pinned={this.pinnedProviders.includes(provider.name)}
pinStateCallback={(pinned: boolean) => {
this.emit(pinned ? 'providerPinned' : 'providerUnpinned', provider.name, provider)}
}
title={provider.name}
>
<div>{provider.name}</div>
</RemixUIGridCell>
})}</RemixUIGridSection>
<RemixUIGridSection
plugin={this}
title='Externals'
hScrollable= {true}
>{this.providers['Externals'].map(provider => {
return <RemixUIGridCell
plugin={this}
pinned={this.pinnedProviders.includes(provider.name)}
pinStateCallback={(pinned: boolean) => {
this.emit(pinned ? 'providerPinned' : 'providerUnpinned', provider.name, provider)}
}
title={provider.name}
>
<div>{provider.name}</div>
</RemixUIGridCell>
})}</RemixUIGridSection>
</RemixUIGridView>
)
}
}

@ -23,7 +23,7 @@ const profile = {
name: 'blockchain',
displayName: 'Blockchain',
description: 'Blockchain - Logic',
methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider', 'getCurrentFork', 'getAccounts', 'web3VM', 'web3', 'getProvider', 'getCurrentNetworkStatus'],
methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider', 'getCurrentFork', 'getAccounts', 'web3VM', 'web3', 'getProvider', 'getCurrentNetworkStatus', 'getAllProviders', 'getPinnedProviders'],
version: packageJson.version
}
@ -44,6 +44,21 @@ export type Transaction = {
timestamp?: number
}
export type Provider = {
options: { [key: string]: string }
dataId: string
name: string
displayName: string
fork: string
isInjected: boolean
isVM: boolean
title: string
init: () => Promise<void>
provider:{
sendAsync: (payload: any) => Promise<void>
}
}
export class Blockchain extends Plugin {
active: boolean
event: EventManager
@ -62,6 +77,7 @@ export class Blockchain extends Plugin {
providers: {[key: string]: VMProvider | InjectedProvider | NodeProvider}
transactionContextAPI: TransactionContextAPI
registeredPluginEvents: string[]
pinnedProviders: string[]
// NOTE: the config object will need to be refactored out in remix-lib
constructor(config: Config) {
@ -93,6 +109,8 @@ export class Blockchain extends Plugin {
this.networkcallid = 0
this.networkStatus = { network: { name: ' - ', id: ' - ' } }
this.registeredPluginEvents = []
this.pinnedProviders = ['vm-cancun', 'vm-shanghai', 'vm-berlin', 'vm-paris', 'vm-london', 'vm-sepolia-fork', 'vm-mainnet-fork', 'vm-custom-fork', 'walletconnect', 'injected-MetaMask', 'basic-http-provider', 'ganache-provider', 'hardhat-provider', 'foundry-provider']
this.setupEvents()
this.setupProviders()
}
@ -116,6 +134,14 @@ export class Blockchain extends Plugin {
})
}
})
this.on('gridProviders', 'providerPinned', (name, provider) => {
this.emit('shouldAddProvidertoUdapp', name, provider)
})
this.on('gridProviders', 'providerUnpinned', (name, provider) => {
this.emit('shouldRemoveProviderFromUdapp', name, provider)
})
}
onDeactivation() {
@ -136,12 +162,12 @@ export class Blockchain extends Plugin {
})
})
this.executionContext.event.register('addProvider', (network) => {
this._triggerEvent('addProvider', [network])
this.executionContext.event.register('providerAdded', (network) => {
this._triggerEvent('providerAdded', [network])
})
this.executionContext.event.register('removeProvider', (name) => {
this._triggerEvent('removeProvider', [name])
this.executionContext.event.register('providerRemoved', (name) => {
this._triggerEvent('providerRemoved', [name])
})
setInterval(() => {
@ -504,7 +530,11 @@ export class Blockchain extends Plugin {
}
changeExecutionContext(context, confirmCb, infoCb, cb) {
return this.executionContext.executionContextChange(context, null, confirmCb, infoCb, cb)
if (context.context === 'item-another-chain') {
this.call('manager', 'activatePlugin', 'gridProviders')
} else {
return this.executionContext.executionContextChange(context, null, confirmCb, infoCb, cb)
}
}
detectNetwork(cb) {
@ -611,7 +641,8 @@ export class Blockchain extends Plugin {
this.executionContext.listenOnLastBlock()
}
addProvider(provider) {
addProvider(provider: Provider) {
if (this.pinnedProviders.includes(provider.name)) this.emit('shouldAddProvidertoUdapp', provider.name, provider)
this.executionContext.addProvider(provider)
}
@ -619,6 +650,14 @@ export class Blockchain extends Plugin {
this.executionContext.removeProvider(name)
}
getAllProviders() {
return this.executionContext.getAllProviders()
}
getPinnedProviders() {
return this.pinnedProviders
}
// TODO : event should be triggered by Udapp instead of TxListener
/** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */
startListening(txlistener) {

@ -123,10 +123,13 @@ export class ExecutionContext {
addProvider (network) {
if (network && network.name && !this.customNetWorks[network.name]) {
this.customNetWorks[network.name] = network
this.event.trigger('addProvider', [network])
}
}
getAllProviders () {
return this.customNetWorks
}
internalWeb3 () {
return web3
}

@ -69,9 +69,9 @@ export const setupEvents = (plugin: RunTab) => {
}
})
plugin.blockchain.event.register('addProvider', provider => addExternalProvider(dispatch, provider))
plugin.on('blockchain', 'shouldAddProvidertoUdapp', (name, provider) => addExternalProvider(dispatch, provider))
plugin.blockchain.event.register('removeProvider', name => removeExternalProvider(dispatch, name))
plugin.on('blockchain', 'shouldRemoveProviderFromUdapp', (name, provider) => removeExternalProvider(dispatch, name))
plugin.blockchain.events.on('newProxyDeployment', (address, date, contractName) => addNewProxyDeployment(dispatch, address, date, contractName))

@ -68,6 +68,17 @@ export function EnvironmentUI(props: EnvironmentProps) {
</span>
</Dropdown.Item>
))}
<Dropdown.Item
key={10000}
onClick={() => {
props.setExecutionContext({ context: 'item-another-chain' })
}}
data-id={`dropdown-item-another-chain`}
>
<span className="">
Pin another chain...
</span>
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</div>

Loading…
Cancel
Save