commit
1579aca1d4
@ -0,0 +1,25 @@ |
||||
import { NightwatchBrowser } from 'nightwatch' |
||||
import EventEmitter from 'events' |
||||
|
||||
class HidePopupPanel extends EventEmitter { |
||||
command(this: NightwatchBrowser) { |
||||
browser |
||||
.perform((done) => { |
||||
browser.execute(function () { |
||||
return localStorage.getItem('did_show_popup_panel') |
||||
}, [], function (result) { |
||||
if (!result.value) { |
||||
browser.waitForElementVisible('*[data-id="popupPanelToggle"]') |
||||
.click('*[data-id="popupPanelToggle"]') |
||||
} |
||||
done() |
||||
}) |
||||
}) |
||||
.perform((done) => { |
||||
done() |
||||
this.emit('complete') |
||||
}) |
||||
} |
||||
} |
||||
|
||||
module.exports = HidePopupPanel |
@ -0,0 +1,123 @@ |
||||
import React from 'react' // eslint-disable-line
|
||||
import { AbstractPanel } from './panel' |
||||
import { PluginRecord, RemixPluginPanel } from '@remix-ui/panel' |
||||
import packageJson from '../../../../../package.json' |
||||
import { PluginViewWrapper } from '@remix-ui/helper' |
||||
import { EventEmitter } from 'events' |
||||
|
||||
import { AppAction, appActionTypes, AppState } from '@remix-ui/app' |
||||
|
||||
const profile = { |
||||
name: 'popupPanel', |
||||
displayName: 'Popup Panel', |
||||
description: 'Remix IDE popup panel', |
||||
version: packageJson.version, |
||||
events: [], |
||||
methods: ['addView', 'removeView', 'showContent', 'showPopupPanel'] |
||||
} |
||||
type popupPanelState = { |
||||
plugins: Record<string, PluginRecord> |
||||
} |
||||
|
||||
export class PopupPanel extends AbstractPanel { |
||||
element: HTMLDivElement |
||||
dispatch: React.Dispatch<any> = () => { } |
||||
appStateDispatch: React.Dispatch<AppAction> = () => { } |
||||
|
||||
constructor(config) { |
||||
super(profile) |
||||
this.event = new EventEmitter() |
||||
} |
||||
|
||||
setDispatch(dispatch: React.Dispatch<any>) { |
||||
this.dispatch = dispatch |
||||
} |
||||
|
||||
setAppStateDispatch(appStateDispatch: React.Dispatch<AppAction>) { |
||||
this.appStateDispatch = appStateDispatch |
||||
} |
||||
|
||||
onActivation() { |
||||
this.renderComponent() |
||||
} |
||||
|
||||
focus(name) { |
||||
this.emit('focusChanged', name) |
||||
super.focus(name) |
||||
this.renderComponent() |
||||
} |
||||
|
||||
addView(profile, view) { |
||||
super.addView(profile, view) |
||||
this.renderComponent() |
||||
this.showContent(profile.name) // should be handled by some click
|
||||
} |
||||
|
||||
removeView(profile) { |
||||
super.removeView(profile) |
||||
this.renderComponent() |
||||
} |
||||
|
||||
async showContent(name) { |
||||
super.showContent(name) |
||||
this.renderComponent() |
||||
} |
||||
|
||||
async showPopupPanel(show) { |
||||
|
||||
this.appStateDispatch({ |
||||
type: appActionTypes.setShowPopupPanel, |
||||
payload: show |
||||
}) |
||||
this.renderComponent() |
||||
} |
||||
|
||||
renderComponent() { |
||||
this.dispatch({ |
||||
plugins: this.plugins |
||||
}) |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<PluginViewWrapper useAppContext={true} plugin={this} /> |
||||
) |
||||
} |
||||
|
||||
updateComponent(state: popupPanelState, appState: Partial<AppState>) { |
||||
return ( |
||||
<div |
||||
className={`px-0 bg-light border-info ${appState?.showPopupPanel ? 'd-flex' : 'd-none'}`} |
||||
style={{ |
||||
maxHeight: '40rem', |
||||
maxWidth: '25rem', |
||||
width: 'max-content', |
||||
height: '40rem', |
||||
position: 'fixed', |
||||
bottom: '2rem', |
||||
right: '1.5rem', |
||||
zIndex: 200, |
||||
boxShadow: "0 1px 7px var(--secondary)" |
||||
}} |
||||
data-id="popupPanelPluginsContainer" |
||||
> |
||||
<div className='d-flex flex-column'> |
||||
<RemixPluginPanel |
||||
header={ |
||||
<span id='popupPanelToggle' className='d-flex flex-row'> |
||||
<button |
||||
data-id='popupPanelToggle' |
||||
className='btn fas fa-angle-double-down' |
||||
onClick={async () => { |
||||
await this.showPopupPanel(false) |
||||
}} |
||||
> |
||||
</button> |
||||
</span> |
||||
} |
||||
plugins={state.plugins} /> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
||||
} |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 65 KiB |
@ -0,0 +1,10 @@ |
||||
import { IFilePanel } from '@remixproject/plugin-api' |
||||
import { StatusEvents } from '@remixproject/plugin-utils' |
||||
|
||||
export interface IPopupPanelAPI { |
||||
events:{ |
||||
} & StatusEvents |
||||
methods: { |
||||
showPopupPanel(state: boolean): void |
||||
} |
||||
} |
@ -1,23 +0,0 @@ |
||||
import { IParams } from "@remix/remix-ai-core"; |
||||
import { StatusEvents } from "@remixproject/plugin-utils"; |
||||
|
||||
export interface IRemixAID { |
||||
events: { |
||||
activated():void, |
||||
onInference():void, |
||||
onInferenceDone():void, |
||||
onStreamResult(streamText: string):void, |
||||
|
||||
} & StatusEvents, |
||||
methods: { |
||||
code_completion(context: string): Promise<string>
|
||||
code_insertion(msg_pfx: string, msg_sfx: string): Promise<string>, |
||||
code_generation(prompt: string): Promise<string | null>, |
||||
code_explaining(code: string, context?: string): Promise<string | null>, |
||||
error_explaining(prompt: string): Promise<string | null>, |
||||
solidity_answer(prompt: string): Promise<string | null>, |
||||
initializeModelBackend(local: boolean, generalModel?, completionModel?): Promise<boolean>, |
||||
chatPipe(pipeMessage: string): Promise<void>, |
||||
ProcessChatRequestBuffer(params:IParams): Promise<void>, |
||||
} |
||||
} |
@ -1,18 +1,35 @@ |
||||
import React from 'react' |
||||
import { useEffect, useState } from 'react' |
||||
import { AppContext } from '@remix-ui/app' |
||||
import React, { useContext, useEffect, useState } from 'react' |
||||
|
||||
interface IPluginViewWrapperProps { |
||||
plugin: any |
||||
useAppContext?: boolean // Optional flag to decide whether to use AppContext
|
||||
} |
||||
|
||||
export const PluginViewWrapper = (props: IPluginViewWrapperProps) => { |
||||
export const PluginViewWrapper = ({ plugin, useAppContext = false }: IPluginViewWrapperProps) => { |
||||
const [state, setState] = useState<any>(null) |
||||
const appContext = useAppContext ? useContext(AppContext) : null |
||||
|
||||
useEffect(() => { |
||||
if (props.plugin.setDispatch) { |
||||
props.plugin.setDispatch(setState) |
||||
if (plugin.setDispatch) { |
||||
plugin.setDispatch(setState) |
||||
} |
||||
if (useAppContext && appContext.appStateDispatch && plugin.setAppStateDispatch) { |
||||
plugin.setAppStateDispatch(appContext.appStateDispatch) |
||||
} |
||||
}, [plugin]) |
||||
|
||||
if (useAppContext && appContext && appContext.appState) { |
||||
return ( |
||||
<> |
||||
{state ? <>{plugin.updateComponent(state, appContext.appState)}</> : <></>} |
||||
</> |
||||
) |
||||
} |
||||
}, []) |
||||
|
||||
return <>{state ? <>{props.plugin.updateComponent(state)}</> : <></>}</> |
||||
return ( |
||||
<> |
||||
{state ? <>{plugin.updateComponent(state)}</> : <></>} |
||||
</> |
||||
) |
||||
} |
||||
|
@ -1,8 +1,8 @@ |
||||
import { PersonaOptions, UserPersona } from '@nlux/react'; |
||||
|
||||
export const user: UserPersona = { |
||||
name: 'Pipper', |
||||
name: 'Remi', |
||||
avatar: 'assets/img/remix-logo-blue.png' |
||||
}; |
||||
|
||||
export const assistantAvatar = 'assets/img/remi-prof.webp'; |
||||
export const assistantAvatar = 'assets/img/aiLogo.svg' |
||||
|
@ -0,0 +1,265 @@ |
||||
export type ChainInfo = { |
||||
id: number | string |
||||
name: string |
||||
} |
||||
|
||||
export type ChainCompatibleInfo = { |
||||
chain: ChainInfo |
||||
minCompilerVersion: string |
||||
evmVersion: HardFork |
||||
} |
||||
|
||||
export type HardFork = |
||||
| 'cancun' |
||||
| 'shanghai' |
||||
| 'paris' |
||||
| 'london' |
||||
| 'berlin' |
||||
| 'istanbul' |
||||
| 'petersburg' |
||||
| 'constantinople' |
||||
| 'byzantium' |
||||
| 'spuriousDragon' |
||||
| 'tangerineWhistle' |
||||
| 'homestead' |
||||
|
||||
export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: string }> = new Map([ |
||||
['cancun', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" }, |
||||
{ id: 5, name: "Goerli" }, |
||||
{ id: 10, name: "Optimism" }, |
||||
{ id: 56, name: "BNB Smart Chain Mainnet" }, |
||||
{ id: 100, name: "Gnosis Chain" }, |
||||
{ id: 137, name: "Polygon Mainnet" }, |
||||
{ id: 250, name: "Fantom Opera" }, |
||||
{ id: 300, name: "zkSync Era Mainnet" }, |
||||
{ id: 42161, name: "Arbitrum One" }, |
||||
{ id: 42170, name: "Arbitrum Nova" }, |
||||
{ id: 43114, name: "Avalanche C-Chain" }, |
||||
{ id: 44787, name: "Celo Alfajores Testnet" }, |
||||
{ id: 59144, name: "Linea Mainnet" }, |
||||
{ id: 59141, name: "Linea Testnet" }, |
||||
{ id: 421614, name: "Arbitrum Sepolia" }, |
||||
{ id: 534352, name: "Scroll" }, |
||||
{ id: 11155111, name: "Sepolia" } |
||||
], |
||||
minCompilerVersion: "0.8.24+commit.e11b9ed9", |
||||
evmVersion: 'cancun' |
||||
}], |
||||
['shanghai', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" }, |
||||
{ id: 5, name: "Goerli" }, |
||||
{ id: 10, name: "Optimism" }, |
||||
{ id: 30, name: "Rootstock Mainnet" }, |
||||
{ id: 56, name: "BNB Smart Chain Mainnet" }, |
||||
{ id: 100, name: "Gnosis Chain" }, |
||||
{ id: 137, name: "Polygon Mainnet" }, |
||||
{ id: 250, name: "Fantom Opera" }, |
||||
{ id: 300, name: "zkSync Era Mainnet" }, |
||||
{ id: 302, name: "zkSync Era Testnet" }, |
||||
{ id: 314, name: "Filecoin - Mainnet" }, |
||||
{ id: 324, name: "zkSync Era Mainnet" }, |
||||
{ id: 369, name: "PulseChain" }, |
||||
{ id: 388, name: "HALO Mainnet" }, |
||||
{ id: 1101, name: "Polygon zkEVM" }, |
||||
{ id: 1088, name: "Metis Andromeda Mainnet" }, |
||||
{ id: 1284, name: "Moonbeam" }, |
||||
{ id: 2000, name: "Dogechain Mainnet" }, |
||||
{ id: 42161, name: "Arbitrum One" }, |
||||
{ id: 42170, name: "Arbitrum Nova" }, |
||||
{ id: 44787, name: "Celo Alfajores Testnet" }, |
||||
{ id: 59144, name: "Linea Mainnet" }, |
||||
{ id: 59141, name: "Linea Testnet" }, |
||||
{ id: 59902, name: "Metis Sepolia Testnet" }, |
||||
{ id: 421614, name: "Arbitrum Sepolia" }, |
||||
{ id: 534352, name: "Scroll" }, |
||||
{ id: 11155111, name: "Sepolia" }, |
||||
{ id: 11155420, name: "Optimism Sepolia Testnet" }, |
||||
{ id: 1666600000, name: "Harmony Mainnet Shard 0" } |
||||
], |
||||
minCompilerVersion: "0.8.20+commit.a1b79de6", |
||||
evmVersion: 'shanghai' |
||||
}], |
||||
['paris', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" }, |
||||
{ id: 5, name: "Goerli" }, |
||||
{ id: 10, name: "Optimism" }, |
||||
{ id: 30, name: "Rootstock Mainnet" }, |
||||
{ id: 56, name: "BNB Smart Chain Mainnet" }, |
||||
{ id: 100, name: "Gnosis Chain" }, |
||||
{ id: 137, name: "Polygon Mainnet" }, |
||||
{ id: 250, name: "Fantom Opera" }, |
||||
{ id: 300, name: "zkSync Era Mainnet" }, |
||||
{ id: 302, name: "zkSync Era Testnet" }, |
||||
{ id: 314, name: "Filecoin - Mainnet" }, |
||||
{ id: 324, name: "zkSync Era Mainnet" }, |
||||
{ id: 369, name: "PulseChain" }, |
||||
{ id: 388, name: "HALO Mainnet" }, |
||||
{ id: 1088, name: "Metis Andromeda Mainnet" }, |
||||
{ id: 1101, name: "Polygon zkEVM" }, |
||||
{ id: 1284, name: "Moonbeam" }, |
||||
{ id: 2000, name: "Dogechain Mainnet" }, |
||||
{ id: 42220, name: "Celo Mainnet" }, |
||||
{ id: 42161, name: "Arbitrum One" }, |
||||
{ id: 42170, name: "Arbitrum Nova" }, |
||||
{ id: 44787, name: "Celo Alfajores Testnet" }, |
||||
{ id: 59144, name: "Linea Mainnet" }, |
||||
{ id: 59141, name: "Linea Testnet" }, |
||||
{ id: 59902, name: "Metis Sepolia Testnet" }, |
||||
{ id: 421614, name: "Arbitrum Sepolia" }, |
||||
{ id: 534352, name: "Scroll" }, |
||||
{ id: 11155111, name: "Sepolia" }, |
||||
{ id: 11155420, name: "Optimism Sepolia Testnet" }, |
||||
{ id: 1666600000, name: "Harmony Mainnet Shard 0" } |
||||
], |
||||
minCompilerVersion: "0.8.18+commit.87f61d96", |
||||
evmVersion: 'paris' |
||||
}], |
||||
['london', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" }, |
||||
{ id: 5, name: "Goerli" }, |
||||
{ id: 10, name: "Optimism" }, |
||||
{ id: 25, name: "Cronos Mainnet" }, |
||||
{ id: 30, name: "Rootstock Mainnet" }, |
||||
{ id: 56, name: "BNB Smart Chain Mainnet" }, |
||||
{ id: 137, name: "Polygon Mainnet" }, |
||||
{ id: 250, name: "Fantom Opera" }, |
||||
{ id: 1280, name: "HALO Mainnet" }, |
||||
{ id: 42161, name: "Arbitrum One" }, |
||||
{ id: 42170, name: "Arbitrum Nova" }, |
||||
{ id: 42220, name: "Celo Mainnet" }, |
||||
{ id: 59144, name: "Linea Mainnet" }, |
||||
{ id: 59141, name: "Linea Testnet" }, |
||||
{ id: 11155111, name: "Sepolia" }, |
||||
], |
||||
minCompilerVersion: "0.8.7+commit.e28d00a7", |
||||
evmVersion: 'london' |
||||
}], |
||||
['berlin', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" }, |
||||
{ id: 5, name: "Goerli" }, |
||||
{ id: 10, name: "Optimism" }, |
||||
{ id: 25, name: "Cronos Mainnet" }, |
||||
{ id: 30, name: "Rootstock Mainnet" }, |
||||
{ id: 56, name: "BNB Smart Chain Mainnet" }, |
||||
{ id: 137, name: "Polygon Mainnet" }, |
||||
{ id: 250, name: "Fantom Opera" }, |
||||
{ id: 1280, name: "HALO Mainnet" }, |
||||
{ id: 42161, name: "Arbitrum One" }, |
||||
{ id: 42170, name: "Arbitrum Nova" }, |
||||
{ id: 42220, name: "Celo Mainnet" }, |
||||
{ id: 59144, name: "Linea Mainnet" }, |
||||
{ id: 59141, name: "Linea Testnet" }, |
||||
{ id: 11155111, name: "Sepolia" } |
||||
], |
||||
minCompilerVersion: "0.8.5+commit.a4f2e591", |
||||
evmVersion: 'berlin' |
||||
}], |
||||
['istanbul', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" }, |
||||
{ id: 5, name: "Goerli" }, |
||||
{ id: 10, name: "Optimism" }, |
||||
{ id: 25, name: "Cronos Mainnet" }, |
||||
{ id: 30, name: "Rootstock Mainnet" }, |
||||
{ id: 56, name: "BNB Smart Chain Mainnet" }, |
||||
{ id: 137, name: "Polygon Mainnet" }, |
||||
{ id: 250, name: "Fantom Opera" }, |
||||
{ id: 1280, name: "HALO Mainnet" }, |
||||
{ id: 42161, name: "Arbitrum One" }, |
||||
{ id: 42170, name: "Arbitrum Nova" }, |
||||
{ id: 42220, name: "Celo Mainnet" }, |
||||
{ id: 59144, name: "Linea Mainnet" }, |
||||
{ id: 59141, name: "Linea Testnet" }, |
||||
{ id: 11155111, name: "Sepolia" } |
||||
], |
||||
minCompilerVersion: "0.5.14+commit.01f1aaa4", |
||||
evmVersion: 'istanbul' |
||||
}], |
||||
['petersburg', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" }, |
||||
{ id: 5, name: "Goerli" }, |
||||
{ id: 11155111, name: "Sepolia" } |
||||
], |
||||
minCompilerVersion: "0.5.5+commit.47a71e8f", |
||||
evmVersion: 'petersburg' |
||||
}], |
||||
['constantinople', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" }, |
||||
{ id: 5, name: "Goerli" }, |
||||
{ id: 11155111, name: "Sepolia" } |
||||
], |
||||
minCompilerVersion: "0.5.5+commit.47a71e8f", |
||||
evmVersion: 'constantinople' |
||||
}], |
||||
['byzantium', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" } |
||||
], |
||||
minCompilerVersion: "0.4.21+commit.dfe3193c", |
||||
evmVersion: 'byzantium' |
||||
}], |
||||
['spuriousDragon', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" } |
||||
], |
||||
minCompilerVersion: "0.4.9+commit.364da425", |
||||
evmVersion: 'spuriousDragon' |
||||
}], |
||||
['tangerineWhistle', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" } |
||||
], |
||||
minCompilerVersion: "0.4.0+commit.acd334c9", |
||||
evmVersion: 'tangerineWhistle' |
||||
}], |
||||
['homestead', { |
||||
chainId: [ |
||||
{ id: 1, name: "Ethereum Mainnet" }, |
||||
{ id: 5, name: "Goerli" }, |
||||
{ id: 11155111, name: "Sepolia" } |
||||
], |
||||
minCompilerVersion: "0.1.2+commit.d0d36e3", |
||||
evmVersion: 'homestead' |
||||
}], |
||||
]) |
||||
|
||||
export function getCompatibleChains(fork: HardFork): ChainInfo[] { |
||||
const forkData = evmMap.get(fork) |
||||
return forkData ? forkData.chainId : [] |
||||
} |
||||
|
||||
export function isChainCompatible(fork: HardFork, chainId: number): boolean { |
||||
const compatibleChains = getCompatibleChains(fork) |
||||
return compatibleChains.some(chain => chain.id === chainId) |
||||
} |
||||
|
||||
export function isChainCompatibleWithAnyFork(chainId: number, forks: HardFork[]): boolean { |
||||
return forks.some(fork => isChainCompatible(fork, chainId)) |
||||
} |
||||
|
||||
export function getCompatibleChain( |
||||
fork: HardFork, |
||||
chainId: number |
||||
): ChainCompatibleInfo | undefined { |
||||
|
||||
for (const [forkKey, forkData] of evmMap) { |
||||
const compatibleChain = forkData.chainId.find(chain => chain.id === chainId) |
||||
if (compatibleChain) { |
||||
return { |
||||
chain: compatibleChain, |
||||
minCompilerVersion: forkData.minCompilerVersion, |
||||
evmVersion: forkKey |
||||
} |
||||
} |
||||
} |
||||
|
||||
return undefined; |
||||
} |
Loading…
Reference in new issue