Merge branch 'desktopmerge' of https://github.com/ethereum/remix-project into desktopoffline

desktopoffline
filip mertens 1 year ago
commit 1f276f245f
  1. 19
      apps/circuit-compiler/src/app/components/compileBtn.tsx
  2. 2
      apps/circuit-compiler/src/app/components/container.tsx
  3. 6
      apps/circuit-compiler/src/app/components/feedback.tsx
  4. 4
      apps/circuit-compiler/src/app/components/options.tsx
  5. 1
      apps/circuit-compiler/src/app/components/r1csBtn.tsx
  6. 6
      apps/circuit-compiler/src/app/components/witness.tsx
  7. 2
      apps/circuit-compiler/src/app/components/witnessToggler.tsx
  8. 18
      apps/circuit-compiler/src/app/services/circomPluginClient.ts
  9. 178
      apps/remix-ide-e2e/src/tests/circom.test.ts
  10. 2
      apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts
  11. 17
      apps/remix-ide/src/app.js
  12. 48
      apps/remix-ide/src/app/files/dgitProvider.ts
  13. 8
      apps/remix-ide/src/app/files/fileManager.ts
  14. 3
      apps/remix-ide/src/app/panels/terminal.js
  15. 4
      apps/remix-ide/src/app/plugins/parser/services/code-parser-antlr-service.ts
  16. 4
      apps/remix-ide/src/app/plugins/parser/services/code-parser-imports.ts
  17. 6
      apps/remix-ide/src/app/plugins/remixd-handle.tsx
  18. 13
      apps/remix-ide/src/app/providers/abstract-provider.tsx
  19. 6
      apps/remix-ide/src/app/providers/injected-provider.tsx
  20. 2
      apps/remix-ide/src/app/state/registry.ts
  21. 2
      apps/remix-ide/src/app/tabs/web3-provider.js
  22. 18
      apps/remix-ide/src/blockchain/blockchain.tsx
  23. 3
      apps/remix-ide/src/blockchain/execution-context.js
  24. 10
      apps/remix-ide/src/remixAppManager.js
  25. 52
      apps/walletconnect/src/services/WalletConnectRemixClient.ts
  26. 11
      libs/ghaction-helper/package.json
  27. 2
      libs/ghaction-helper/src/methods.ts
  28. 10
      libs/remix-analyzer/package.json
  29. 8
      libs/remix-astwalker/package.json
  30. 14
      libs/remix-debug/package.json
  31. 8
      libs/remix-lib/package.json
  32. 8
      libs/remix-lib/src/execution/txHelper.ts
  33. 16
      libs/remix-lib/src/execution/txRunnerWeb3.ts
  34. 2
      libs/remix-lib/src/hash.ts
  35. 9
      libs/remix-simulator/package.json
  36. 5
      libs/remix-simulator/src/methods/transactions.ts
  37. 2
      libs/remix-simulator/src/vm-context.ts
  38. 8
      libs/remix-solidity/package.json
  39. 12
      libs/remix-tests/package.json
  40. 2
      libs/remix-ui/app/src/index.ts
  41. 8
      libs/remix-ui/app/src/lib/remix-app/context/context.tsx
  42. 5
      libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx
  43. 8
      libs/remix-ui/home-tab/src/lib/components/homeTablangOptions.tsx
  44. 7
      libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx
  45. 5
      libs/remix-ui/panel/src/lib/main/main-panel.tsx
  46. 5
      libs/remix-ui/run-tab/src/lib/components/mainnet.tsx
  47. 4
      libs/remix-ui/search/src/lib/components/results/SearchHelper.ts
  48. 2
      libs/remix-ui/solidity-compiler/src/lib/api/compiler-api.ts
  49. 7
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  50. 8
      libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx
  51. 4
      libs/remix-ui/terminal/src/lib/components/Context.tsx
  52. 4
      libs/remix-ui/terminal/src/lib/components/Table.tsx
  53. 8
      libs/remix-ui/workspace/src/lib/actions/index.ts
  54. 5
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  55. 7
      libs/remix-ui/workspace/src/lib/components/electron-menu.tsx
  56. 7
      libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx
  57. 7
      libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx
  58. 27
      libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx
  59. 6
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  60. 3
      libs/remix-ui/workspace/src/lib/types/index.ts
  61. 15
      libs/remix-ui/workspace/src/lib/utils/index.ts
  62. 4
      libs/remix-url-resolver/package.json
  63. 6
      libs/remix-ws-templates/package.json
  64. 2
      libs/remixd/package.json
  65. 4
      package.json

@ -9,20 +9,21 @@ export function CompileBtn () {
return (
<CustomTooltip
placement="auto"
tooltipId="overlay-tooltip-compile"
tooltipText={
<div className="text-left">
<div>
<b>Ctrl+S</b> to compile {appState.filePath}
</div>
placement="auto"
tooltipId="overlay-tooltip-compile"
tooltipText={
<div className="text-left">
<div>
<b>Ctrl+S</b> to compile {appState.filePath}
</div>
}
>
</div>
}
>
<button
className="btn btn-primary btn-block d-block w-100 text-break mb-1 mt-3"
onClick={() => { compileCircuit(plugin, appState) }}
disabled={(appState.filePath === "") || (appState.status === "compiling") || (appState.status === "generating")}
data-id="compile_circuit_btn"
>
<div className="d-flex align-items-center justify-content-center">
<RenderIf condition={appState.status === 'compiling'}>

@ -70,7 +70,7 @@ export function Container () {
<WitnessSection plugin={circuitApp.plugin} signalInputs={circuitApp.appState.signalInputs} status={circuitApp.appState.status} />
</WitnessToggler>
</RenderIf>
<RenderIf condition={circuitApp.appState.status !== 'compiling' && circuitApp.appState.status !== 'computing' && circuitApp.appState.status !== 'generating'}>
<RenderIf condition={(circuitApp.appState.status !== 'compiling') && (circuitApp.appState.status !== 'computing') && (circuitApp.appState.status !== 'generating')}>
<CompilerFeedback feedback={circuitApp.appState.feedback} filePathToId={circuitApp.appState.filePathToId} openErrorLocation={handleOpenErrorLocation} hideWarnings={circuitApp.appState.hideWarnings} />
</RenderIf>
</div>

@ -21,7 +21,7 @@ export function CompilerFeedback ({ feedback, filePathToId, hideWarnings, openEr
<div>
<div className="circuit_errors_box py-4">
<RenderIf condition={ (typeof feedback === "string") && showException }>
<div className="circuit_feedback error alert alert-danger">
<div className="circuit_feedback error alert alert-danger" data-id="circuit_feedback">
<span> { feedback } </span>
<div className="close" data-id="renderer" onClick={handleCloseException}>
<i className="fas fa-times"></i>
@ -39,12 +39,12 @@ export function CompilerFeedback ({ feedback, filePathToId, hideWarnings, openEr
Array.isArray(feedback) && feedback.map((response, index) => (
<div key={index} onClick={() => handleOpenError(response)}>
<RenderIf condition={response.type === 'Error'}>
<div className={`circuit_feedback ${response.type.toLowerCase()} alert alert-danger`}>
<div className={`circuit_feedback ${response.type.toLowerCase()} alert alert-danger`} data-id="circuit_feedback">
<FeedbackAlert message={response.message} location={ response.labels[0] ? response.labels[0].message + ` ${filePathToId[response.labels[0].file_id]}:${response.labels[0].range.start}:${response.labels[0].range.end}` : null} />
</div>
</RenderIf>
<RenderIf condition={(response.type === 'Warning') && !hideWarnings}>
<div className={`circuit_feedback ${response.type.toLowerCase()} alert alert-warning`}>
<div className={`circuit_feedback ${response.type.toLowerCase()} alert alert-warning`} data-id="circuit_feedback">
<FeedbackAlert message={response.message} location={null} />
</div>
</RenderIf>

@ -14,7 +14,7 @@ export function CompileOptions ({autoCompile, hideWarnings, setCircuitAutoCompil
checked={autoCompile}
id="autoCompileCircuit"
/>
<label className="form-check-label custom-control-label" htmlFor="autoCompileCircuit">
<label className="form-check-label custom-control-label" htmlFor="autoCompileCircuit" data-id="auto_compile_circuit_checkbox_input">
<FormattedMessage id="circuit.autoCompile" />
</label>
</div>
@ -27,7 +27,7 @@ export function CompileOptions ({autoCompile, hideWarnings, setCircuitAutoCompil
title="Hide warnings"
checked={hideWarnings}
/>
<label className="form-check-label custom-control-label" htmlFor="hideCircuitWarnings">
<label className="form-check-label custom-control-label" htmlFor="hideCircuitWarnings" data-id="hide_circuit_warnings_checkbox_input">
<FormattedMessage id="solidity.hideWarnings" />
</label>
</div>

@ -12,6 +12,7 @@ export function R1CSBtn () {
className="btn btn-secondary btn-block d-block w-100 text-break mb-1 mt-2"
onClick={() => { generateR1cs(plugin, appState) }}
disabled={(appState.filePath === "") || (appState.status === "compiling") || (appState.status === "generating") || (appState.status === "computing")}
data-id="generate_r1cs_btn"
>
<CustomTooltip
placement="auto"

@ -26,14 +26,16 @@ export function WitnessSection ({ plugin, signalInputs, status }: {plugin: Circo
<label className="circuit_inner_label form-check-label" htmlFor="circuitPrimeSelector">
<FormattedMessage id="circuit.signalInput" /> { input }
</label>
<input className="form-control m-0 txinput" placeholder={input} name={input} onChange={handleSignalInput} />
<input className="form-control m-0 txinput" placeholder={input} name={input} onChange={handleSignalInput} data-id={`circuit_input_${input}`} />
</div>
))
}
<button
className="btn btn-sm btn-secondary"
onClick={() => { computeWitness(plugin, status, witnessValues) }}
disabled={(status === "compiling") || (status === "generating") || (status === "computing")}>
disabled={(status === "compiling") || (status === "generating") || (status === "computing")}
data-id="compute_witness_btn"
>
<RenderIf condition={status === 'computing'}>
<i className="fas fa-sync fa-spin mr-2" aria-hidden="true"></i>
</RenderIf>

@ -11,7 +11,7 @@ export function WitnessToggler ({ children }: { children: JSX.Element }) {
return (
<div>
<div className="d-flex circuit_config_section justify-content-between" onClick={toggleConfigurations}>
<div className="d-flex circuit_config_section justify-content-between" onClick={toggleConfigurations} data-id="witness_toggler">
<div className="d-flex">
<label className="mt-1 circuit_config_section">
<FormattedMessage id="circuit.computeWitness" />

@ -32,7 +32,7 @@ export class CircomPluginClient extends PluginClient {
this.internalEvents.emit('circom_activated')
}
async parse(path: string, fileContent?: string): Promise<CompilerReport[]> {
async parse(path: string, fileContent?: string): Promise<[CompilerReport[], Record<string, string>]> {
if (!fileContent) {
// @ts-ignore
fileContent = await this.call('fileManager', 'readFile', path)
@ -45,7 +45,7 @@ export class CircomPluginClient extends PluginClient {
try {
const result: CompilerReport[] = JSON.parse(parsedOutput.report())
const mapReportFilePathToId = {}
const mapReportFilePathToId: Record<string, string> = {}
if (result.length === 0) {
// @ts-ignore
@ -101,10 +101,8 @@ export class CircomPluginClient extends PluginClient {
await this.call('editor', 'clearErrorMarkers', [path])
}
}
this.internalEvents.emit('circuit_parsing_done', result, mapReportFilePathToId)
return result
return [result, mapReportFilePathToId]
} catch (e) {
throw new Error(e)
}
@ -112,7 +110,7 @@ export class CircomPluginClient extends PluginClient {
async compile(path: string, compilationConfig?: CompilationConfig): Promise<void> {
this.internalEvents.emit('circuit_compiling_start')
const parseErrors = await this.parse(path)
const [parseErrors, filePathToId] = await this.parse(path)
if (parseErrors && (parseErrors.length > 0)) {
if (parseErrors[0].type === 'Error') {
@ -121,6 +119,8 @@ export class CircomPluginClient extends PluginClient {
} else if (parseErrors[0].type === 'Warning') {
this.internalEvents.emit('circuit_parsing_warning', parseErrors)
}
} else {
this.internalEvents.emit('circuit_parsing_done', parseErrors, filePathToId)
}
if (compilationConfig) {
const { prime, version } = compilationConfig
@ -160,7 +160,7 @@ export class CircomPluginClient extends PluginClient {
async generateR1cs (path: string, compilationConfig?: CompilationConfig): Promise<void> {
this.internalEvents.emit('circuit_generating_r1cs_start')
const parseErrors = await this.parse(path)
const [parseErrors, filePathToId] = await this.parse(path)
if (parseErrors && (parseErrors.length > 0)) {
if (parseErrors[0].type === 'Error') {
@ -169,6 +169,8 @@ export class CircomPluginClient extends PluginClient {
} else if (parseErrors[0].type === 'Warning') {
this.internalEvents.emit('circuit_parsing_warning', parseErrors)
}
} else {
this.internalEvents.emit('circuit_parsing_done', parseErrors, filePathToId)
}
if (compilationConfig) {
const { prime, version } = compilationConfig

@ -0,0 +1,178 @@
'use strict'
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},
'Should create semaphore workspace template #group1 #group2 #group3 #group4': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=semaphore]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits/semaphore.circom"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/run_setup.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates/groth16_verifier.sol.ejs"]')
},
'Should compile a simple circuit using editor play button #group1': function (browser: NightwatchBrowser) {
browser
.click('[data-id="treeViewLitreeViewItemcircuits/simple.circom"]')
.waitForElementPresent('[data-path="Semaphore - 1/circuits/simple.circom"]')
.waitForElementVisible('[data-path="Semaphore - 1/circuits/simple.circom"]')
.click('[data-id="play-editor"]')
.waitForElementPresent('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wasm"]')
.waitForElementVisible('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wasm"]')
},
'Should compute a witness for a simple circuit #group1': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('circuit-compiler')
.frame(0)
.waitForElementVisible('[data-id="witness_toggler"]')
.click('[data-id="witness_toggler"]')
.waitForElementVisible('[data-id="compute_witness_btn"]')
.waitForElementVisible('[data-id="circuit_input_a"]')
.waitForElementVisible('[data-id="circuit_input_b"]')
.setValue('[data-id="circuit_input_a"]', '1')
.setValue('[data-id="circuit_input_b"]', '2')
.click('[data-id="compute_witness_btn"]')
.frameParent()
.clickLaunchIcon('filePanel')
.waitForElementPresent('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wtn"]')
.waitForElementVisible('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wtn"]')
},
'Should compile a simple circuit using compile button in circom plugin #group2': function (browser: NightwatchBrowser) {
browser
.click('[data-id="treeViewLitreeViewItemcircuits/simple.circom"]')
.waitForElementPresent('[data-path="Semaphore - 1/circuits/simple.circom"]')
.waitForElementVisible('[data-path="Semaphore - 1/circuits/simple.circom"]')
.clickLaunchIcon('circuit-compiler')
.frame(0)
.waitForElementPresent('button[data-id="compile_circuit_btn"]')
.waitForElementVisible('button[data-id="compile_circuit_btn"]')
.click('button[data-id="compile_circuit_btn"]')
.frameParent()
.clickLaunchIcon('filePanel')
.waitForElementPresent('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wasm"]')
.waitForElementVisible('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wasm"]')
},
'Should generate R1CS for a simple circuit #group2': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('circuit-compiler')
.frame(0)
.waitForElementPresent('button[data-id="generate_r1cs_btn"]')
.waitForElementVisible('button[data-id="generate_r1cs_btn"]')
.click('button[data-id="generate_r1cs_btn"]')
.frameParent()
.clickLaunchIcon('filePanel')
.waitForElementPresent('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.r1cs"]')
.waitForElementVisible('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.r1cs"]')
},
'Should compile a simple circuit using CTRL + S from the editor #group3': function (browser: NightwatchBrowser) {
browser
.click('[data-id="treeViewLitreeViewItemcircuits/simple.circom"]')
.waitForElementPresent('[data-path="Semaphore - 1/circuits/simple.circom"]')
.waitForElementVisible('[data-path="Semaphore - 1/circuits/simple.circom"]')
.perform(function () {
const actions = this.actions({async: true})
return actions.keyDown(this.Keys.CONTROL).sendKeys('s')
})
.waitForElementPresent('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wasm"]')
.waitForElementVisible('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wasm"]')
},
'Should display warnings for compiled circuit without pragma version #group4': function (browser: NightwatchBrowser) {
browser
.click('[data-id="treeViewLitreeViewItemcircuits/simple.circom"]')
.waitForElementPresent('[data-path="Semaphore - 1/circuits/simple.circom"]')
.waitForElementVisible('[data-path="Semaphore - 1/circuits/simple.circom"]')
.setEditorValue(warningCircuit)
.clickLaunchIcon('circuit-compiler')
.frame(0)
.waitForElementPresent('button[data-id="compile_circuit_btn"]')
.waitForElementVisible('button[data-id="compile_circuit_btn"]')
.click('button[data-id="compile_circuit_btn"]')
.waitForElementPresent('[data-id="circuit_feedback"]')
.waitForElementVisible('[data-id="circuit_feedback"]')
.assert.hasClass('[data-id="circuit_feedback"]', 'alert-warning')
.waitForElementContainsText('[data-id="circuit_feedback"]', 'File circuits/simple.circom does not include pragma version. Assuming pragma version (2, 1, 5)')
},
'Should hide/show warnings for compiled circuit #group4': function (browser: NightwatchBrowser) {
browser
.click('[data-id="hide_circuit_warnings_checkbox_input"]')
.waitForElementNotPresent('[data-id="circuit_feedback"]')
.click('[data-id="hide_circuit_warnings_checkbox_input"]')
.waitForElementVisible('[data-id="circuit_feedback"]')
.waitForElementContainsText('[data-id="circuit_feedback"]', 'File circuits/simple.circom does not include pragma version. Assuming pragma version (2, 1, 5)')
},
'Should display error for invalid circuit #group4': function (browser: NightwatchBrowser) {
browser
.frameParent()
.setEditorValue(errorCircuit)
.frame(0)
.waitForElementPresent('button[data-id="compile_circuit_btn"]')
.waitForElementVisible('button[data-id="compile_circuit_btn"]')
.click('button[data-id="compile_circuit_btn"]')
.waitForElementPresent('[data-id="circuit_feedback"]')
.assert.hasClass('[data-id="circuit_feedback"]', 'alert-danger')
.waitForElementContainsText('[data-id="circuit_feedback"]', 'No main specified in the project structure')
},
'Should auto compile circuit #group4': function (browser: NightwatchBrowser) {
browser
.click('[data-id="auto_compile_circuit_checkbox_input"]')
.frameParent()
.setEditorValue(validCircuit)
.frame(0)
.waitForElementNotPresent('[data-id="circuit_feedback"]')
.frameParent()
.clickLaunchIcon('filePanel')
.waitForElementPresent('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wasm"]')
}
}
const warningCircuit = `
template Multiplier2() {
signal input a;
signal input b;
signal output c;
c <== a*b;
}
component main = Multiplier2();
`
const errorCircuit = `
pragma circom 2.0.0;
template Multiplier2() {
signal input a;
signal input b;
signal output c;
c <== a*b;
}
`
const validCircuit = `
pragma circom 2.0.0;
template Multiplier2() {
signal input a;
signal input b;
signal output c;
c <== a*b;
}
component main = Multiplier2();
`

@ -132,7 +132,7 @@ module.exports = {
.click('*[data-id="testTabCheckAllTests"]')
.clickElementAtPosition('.singleTestLabel', 1)
.scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]')
.waitForElementContainsText('*[data-id="testTabSolidityUnitTestsOutput"]', 'revert Deploy Failed', 120000)
.waitForElementContainsText('*[data-id="testTabSolidityUnitTestsOutput"]', 'contract deployment failed: revert', 120000)
},
'Should fail when parameters are passed to method in test contract #group3': function (browser: NightwatchBrowser) {

@ -71,6 +71,7 @@ const Config = require('./config')
const FileManager = require('./app/files/fileManager')
import FileProvider from "./app/files/fileProvider"
import { appPlatformTypes } from '@remix-ui/app'
const DGitProvider = require('./app/files/dgitProvider')
const WorkspaceFileProvider = require('./app/files/workspaceFileProvider')
@ -87,10 +88,22 @@ const Terminal = require('./app/panels/terminal')
const {TabProxy} = require('./app/panels/tab-proxy.js')
export class platformApi {
get name () {
return isElectron() ? appPlatformTypes.desktop : appPlatformTypes.web
}
isDesktop () {
return isElectron()
}
}
class AppComponent {
constructor() {
const PlatFormAPi = new platformApi()
Registry.getInstance().put({
api: PlatFormAPi,
name: 'platform'
})
this.appManager = new RemixAppManager({})
this.queryParams = new QueryParams()
this._components = {}
@ -129,6 +142,8 @@ class AppComponent {
api: this._components.filesProviders,
name: 'fileproviders'
})
}
async run() {

@ -14,7 +14,7 @@ import JSZip from 'jszip'
import path from 'path'
import FormData from 'form-data'
import axios from 'axios'
import isElectron from 'is-electron'
import Registry from '../state/registry'
const profile = {
name: 'dGitProvider',
@ -57,7 +57,7 @@ class DGitProvider extends Plugin {
async getGitConfig() {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return {
fs: window.remixFileSystem,
dir: '/'
@ -89,7 +89,7 @@ class DGitProvider extends Plugin {
}
async init(input?) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
await this.call('isogit', 'init', {
defaultBranch: (input && input.branch) || 'main'
})
@ -105,7 +105,7 @@ class DGitProvider extends Plugin {
}
async version() {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return await this.call('isogit', 'version')
}
@ -115,7 +115,7 @@ class DGitProvider extends Plugin {
async status(cmd) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
const status = await this.call('isogit', 'status', cmd)
return status
@ -132,7 +132,7 @@ class DGitProvider extends Plugin {
async add(cmd) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
await this.call('isogit', 'add', cmd)
} else {
await git.add({
@ -146,7 +146,7 @@ class DGitProvider extends Plugin {
async rm(cmd) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
await this.call('isogit', 'rm', cmd)
} else {
await git.remove({
@ -160,7 +160,7 @@ class DGitProvider extends Plugin {
async reset(cmd) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
await this.call('isogit', 'reset', cmd)
} else {
await git.resetIndex({
@ -174,7 +174,7 @@ class DGitProvider extends Plugin {
async checkout(cmd, refresh = true) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
await this.call('isogit', 'checkout', cmd)
} else {
await git.checkout({
@ -192,7 +192,7 @@ class DGitProvider extends Plugin {
async log(cmd) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
const status = await this.call('isogit', 'log', {
...cmd,
depth: 10
@ -211,7 +211,7 @@ class DGitProvider extends Plugin {
}
async remotes(config) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return await this.call('isogit', 'remotes', config)
}
@ -227,7 +227,7 @@ class DGitProvider extends Plugin {
async branch(cmd, refresh = true) {
let status
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
status = await this.call('isogit', 'branch', cmd)
} else {
status = await git.branch({
@ -248,7 +248,7 @@ class DGitProvider extends Plugin {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return await this.call('isogit', 'currentbranch')
}
@ -265,7 +265,7 @@ class DGitProvider extends Plugin {
async branches(config) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return await this.call('isogit', 'branches')
}
@ -288,7 +288,7 @@ class DGitProvider extends Plugin {
async commit(cmd) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
try {
await this.call('isogit', 'init')
const sha = await this.call('isogit', 'commit', cmd)
@ -315,7 +315,7 @@ class DGitProvider extends Plugin {
async lsfiles(cmd) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return await this.call('isogit', 'lsfiles', cmd)
}
@ -328,7 +328,7 @@ class DGitProvider extends Plugin {
async resolveref(cmd) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return await this.call('isogit', 'resolveref', cmd)
}
@ -340,7 +340,7 @@ class DGitProvider extends Plugin {
}
async readblob(cmd) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
const readBlobResult = await this.call('isogit', 'readblob', cmd)
return readBlobResult
}
@ -370,7 +370,7 @@ class DGitProvider extends Plugin {
}
async addremote(input) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
await this.call('isogit', 'addremote', { url: input.url, remote: input.remote })
return
}
@ -378,7 +378,7 @@ class DGitProvider extends Plugin {
}
async delremote(input) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
await this.call('isogit', 'delremote', { remote: input.remote })
return
}
@ -391,7 +391,7 @@ class DGitProvider extends Plugin {
async clone(input, workspaceName, workspaceExists = false) {
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
const folder = await this.call('fs', 'selectFolder')
if (!folder) return false
const cmd = {
@ -442,7 +442,7 @@ class DGitProvider extends Plugin {
},
input,
}
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
return await this.call('isogit', 'push', cmd)
} else {
@ -470,7 +470,7 @@ class DGitProvider extends Plugin {
input,
}
let result
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
result = await this.call('isogit', 'pull', cmd)
}
else {
@ -501,7 +501,7 @@ class DGitProvider extends Plugin {
input
}
let result
if (isElectron()) {
if ((Registry.getInstance().get('platform').api.isDesktop())) {
result = await this.call('isogit', 'fetch', cmd)
} else {
const cmd2 = {

@ -10,8 +10,6 @@ import { fileChangedToastMsg, recursivePasteToastMsg, storageFullMessage } from
import helper from '../../lib/helper.js'
import { RemixAppManager } from '../../remixAppManager'
import isElectron from 'is-electron'
/*
attach to files event (removed renamed)
trigger: currentFileChanged
@ -157,7 +155,7 @@ class FileManager extends Plugin {
refresh() {
const provider = this.fileProviderOf('/')
// emit rootFolderChanged so that File Explorer reloads the file tree
if(isElectron()){
if(Registry.getInstance().get('platform').api.isDesktop()){
provider.event.emit('refresh')
}else{
provider.event.emit('rootFolderChanged', provider.workspace || '/')
@ -791,7 +789,7 @@ class FileManager extends Plugin {
return this._deps.filesProviders.localhost
}
if(isElectron()){
if(Registry.getInstance().get('platform').api.isDesktop()){
return this._deps.filesProviders.electron
}
return this._deps.filesProviders.workspace
@ -916,7 +914,7 @@ class FileManager extends Plugin {
}
currentWorkspace() {
if(isElectron()){
if(Registry.getInstance().get('platform').api.isDesktop()){
return ''
}

@ -6,7 +6,6 @@ import * as packageJson from '../../../../../package.json'
import Registry from '../state/registry'
import { PluginViewWrapper } from '@remix-ui/helper'
import vm from 'vm'
import isElectron from 'is-electron'
const EventManager = require('../../lib/events')
import { CompilerImports } from '@remix-project/core-plugin' // eslint-disable-line
@ -115,7 +114,7 @@ class Terminal extends Plugin {
}
updateComponent(state) {
return isElectron() ? <RemixUiXterminals onReady={state.onReady} plugin={state.plugin}>
return (Registry.getInstance().get('platform').api.isDesktop()) ? <RemixUiXterminals onReady={state.onReady} plugin={state.plugin}>
</RemixUiXterminals>
: <RemixUiTerminal
plugin={state.plugin}

@ -4,7 +4,7 @@ import { AstNode } from "@remix-project/remix-solidity"
import { CodeParser } from "../code-parser"
import { antlr } from '../types'
import { pathToFileURL } from 'url'
import isElectron from 'is-electron'
import Registry from "../../../state/registry"
const SolidityParser = (window as any).SolidityParser = (window as any).SolidityParser || []
@ -46,7 +46,7 @@ export default class CodeParserAntlrService {
this.worker = new Worker(new URL('./antlr-worker', import.meta.url))
this.worker.postMessage({
cmd: 'load',
url: isElectron() ? 'assets/js/parser/antlr.js' : document.location.protocol + '//' + document.location.host + '/assets/js/parser/antlr.js',
url: Registry.getInstance().get('platform').api.isDesktop() ? 'assets/js/parser/antlr.js' : document.location.protocol + '//' + document.location.host + '/assets/js/parser/antlr.js',
})
const self = this

@ -1,6 +1,6 @@
'use strict'
import Registry from "../../../state/registry";
import { CodeParser } from "../code-parser";
import isElectron from 'is-electron'
export type CodeParserImportsData = {
files?: string[],
@ -40,7 +40,7 @@ export default class CodeParserImports {
}
setFileTree = async () => {
if (isElectron()) {
if (Registry.getInstance().get('platform').api.isDesktop()) {
const files = await this.plugin.call('ripgrep', 'glob', '/', '**/*.sol')
// only get path property of files
this.data.files = files.map((x) => x.path)

@ -1,12 +1,12 @@
/* eslint-disable no-unused-vars */
import React, {useRef, useState, useEffect} from 'react' // eslint-disable-line
import isElectron from 'is-electron'
import {WebsocketPlugin} from '@remixproject/engine-web'
import * as packageJson from '../../../../../package.json'
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import {version as remixdVersion} from '../../../../../libs/remixd/package.json'
import {PluginManager} from '@remixproject/engine'
import {AppModal, AlertModal} from '@remix-ui/app'
import {AppModal, AlertModal, appPlatformTypes} from '@remix-ui/app'
import Registry from '../state/registry'
const LOCALHOST = ' - connect to localhost - '
@ -112,7 +112,7 @@ export class RemixdHandle extends WebsocketPlugin {
}
if (this.localhostProvider.isConnected()) {
this.deactivate()
} else if (!isElectron()) {
} else if (!(Registry.getInstance().get('platform').api.isDektop())) {
// warn the user only if he/she is in the browser context
const mod: AppModal = {
id: 'remixdConnect',

@ -14,11 +14,15 @@ export type JsonDataResult = {
id: number
jsonrpc: string // version
result?: any
error?: any
error?: {
code: number,
message: string
data?: string
}
errorData?: any
}
export type RejectRequest = (error: Error) => void
export type RejectRequest = (error: JsonDataResult) => void
export type SuccessRequest = (data: JsonDataResult) => void
export interface IProvider {
@ -98,7 +102,7 @@ export abstract class AbstractProvider extends Plugin implements IProvider {
sendAsync(data: JsonDataRequest): Promise<JsonDataResult> {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve, reject) => {
if (!this.provider) return reject(new Error('provider node set'))
if (!this.provider) return reject({jsonrpc: '2.0', id: data.id, error: { message: 'provider node set', code: -32603 } } as JsonDataResult)
this.sendAsyncInternal(data, resolve, reject)
})
}
@ -128,7 +132,8 @@ export abstract class AbstractProvider extends Plugin implements IProvider {
if (error && error.message && error.message.includes('net_version') && error.message.includes('SERVER_ERROR')) {
this.switchAway(true)
}
reject(error)
error.code = -32603
reject({jsonrpc: '2.0', error, id: data.id})
}
} else {
const result = data.method === 'net_listening' ? 'canceled' : []

@ -80,7 +80,7 @@ export abstract class InjectedProvider extends Plugin implements IProvider {
this.call('notification', 'toast', 'No injected provider (e.g Metamask) has been found.')
return resolve({
jsonrpc: '2.0',
error: 'no injected provider found',
error: { message: 'no injected provider found', code: -32603 },
id: data.id
})
}
@ -89,7 +89,7 @@ export abstract class InjectedProvider extends Plugin implements IProvider {
if (web3Provider.request) resultData = await web3Provider.request({method: data.method, params: data.params})
else if (web3Provider.send) resultData = await web3Provider.send(data.method, data.params)
else {
resolve({jsonrpc: '2.0', error: 'provider not valid', id: data.id})
resolve({jsonrpc: '2.0', error: { message: 'provider not valid', code: -32603 }, id: data.id})
return
}
if (resultData) {
@ -98,7 +98,7 @@ export abstract class InjectedProvider extends Plugin implements IProvider {
}
resolve({jsonrpc: '2.0', result: resultData, id: data.id})
} else {
resolve({jsonrpc: '2.0', error: 'no return data provided', id: data.id})
resolve({jsonrpc: '2.0', result: null, id: data.id})
}
} catch (error) {
if (error.data && error.data.originalError && error.data.originalError.data) {

@ -29,7 +29,7 @@ export default class Registry {
return server
}
public get (name: string) {
public get (name: string): registryEntry {
const state = this.state[name]
if (!state) return
const server = state.server

@ -64,7 +64,7 @@ export class Web3ProviderModule extends Plugin {
try {
resultFn(null, await provider.sendAsync(payload))
} catch (e) {
resultFn(e.message)
resultFn(e.error ? new Error(e.error) : new Error(e))
}
} else {
reject(new Error('User denied permission'))

@ -940,12 +940,20 @@ export class Blockchain extends Plugin {
cb(null, txResult, address, returnValue)
} catch (error) {
if (this.isInjectedWeb3()) {
const errorMessage = error.innerError ? error.innerError.message : error.message
const errorData = error.innerError ? error.innerError.data : error.data
const buildError = async (errorMessage, errorData) => {
const compiledContracts = await this.call('compilerArtefacts', 'getAllContractDatas')
const injectedError = txExecution.checkError({ errorMessage, errorData }, compiledContracts)
cb(injectedError.message)
return txExecution.checkError({ errorMessage, errorData }, compiledContracts)
}
let errorMessage
let errorData
if (error.innerError) {
errorMessage = error.innerError.message
errorData = error.innerError.data
cb((await buildError(errorMessage, errorData)).message)
} else if (error.message || error.data) {
errorMessage = error.message
errorData = error.data
cb((await buildError(errorMessage, errorData)).message)
} else
cb(error)
}

@ -7,12 +7,14 @@ const _paq = window._paq = window._paq || []
let web3
const config = { defaultTransactionType: '0x0' }
if (typeof window !== 'undefined' && typeof window.ethereum !== 'undefined') {
var injectedProvider = window.ethereum
web3 = new Web3(injectedProvider)
} else {
web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
}
web3.eth.setConfig(config)
/*
trigger contextChanged, web3EndpointChanged
@ -59,6 +61,7 @@ export class ExecutionContext {
}
setWeb3 (context, web3) {
web3.setConfig(config)
this.customWeb3[context] = web3
}

@ -2,7 +2,8 @@ import {PluginManager} from '@remixproject/engine'
import {EventEmitter} from 'events'
import {QueryParams} from '@remix-project/remix-lib'
import {IframePlugin} from '@remixproject/engine-web'
const isElectron = require('is-electron')
import Registry from './app/state/registry'
const _paq = (window._paq = window._paq || [])
// requiredModule removes the plugin from the plugin manager list on UI
@ -78,9 +79,6 @@ let requiredModules = [ // services + layout views + system views
'home'
]
if (isElectron()) {
requiredModules = [...requiredModules, 'fs', 'electronTemplates', 'isogit', 'remix-templates', 'electronconfig']
}
// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)
@ -146,6 +144,10 @@ export class RemixAppManager extends PluginManager {
this.event = new EventEmitter()
this.pluginsDirectory = 'https://raw.githubusercontent.com/ethereum/remix-plugins-directory/master/build/metadata.json'
this.pluginLoader = new PluginLoader()
if (Registry.getInstance().get('platform').api.isDesktop()) {
requiredModules = [...requiredModules, 'fs', 'electronTemplates', 'isogit', 'remix-templates', 'electronconfig']
}
}
async canActivatePlugin(from, to) {

@ -24,6 +24,7 @@ export class WalletConnectRemixClient extends PluginClient {
chains: Chain[]
currentChain: number
internalEvents: EventManager
currentAcount: string
constructor() {
super()
@ -59,7 +60,9 @@ export class WalletConnectRemixClient extends PluginClient {
]
const {publicClient} = configureChains(this.chains, [
w3mProvider({projectId: PROJECT_ID})
])
], {
pollingInterval: 5000
})
this.wagmiConfig = createConfig({
autoConnect: false,
@ -75,13 +78,17 @@ export class WalletConnectRemixClient extends PluginClient {
subscribeToEvents() {
this.wagmiConfig.subscribe((event) => {
if (event.status === 'connected') {
this.emit('accountsChanged', [event.data.account])
if (event.data.account !== this.currentAcount) {
this.currentAcount = event.data.account
this.emit('accountsChanged', [event.data.account])
}
if (this.currentChain !== event.data.chain.id) {
this.currentChain = event.data.chain.id
this.emit('chainChanged', event.data.chain.id)
}
} else if (event.status === 'disconnected') {
this.emit('accountsChanged', [])
this.currentAcount = ''
this.emit('chainChanged', 0)
this.currentChain = 0
}
@ -106,25 +113,44 @@ export class WalletConnectRemixClient extends PluginClient {
if (provider.isMetaMask) {
return new Promise((resolve) => {
provider.sendAsync(data, (err, response) => {
if (err) {
console.error(err)
return resolve({jsonrpc: '2.0', result: [], id: data.id})
provider.sendAsync(data, (error, response) => {
if (error) {
if (error.data && error.data.originalError && error.data.originalError.data) {
resolve({
jsonrpc: '2.0',
error: error.data.originalError,
id: data.id
})
} else if (error.data && error.data.message) {
resolve({
jsonrpc: '2.0',
error: error.data && error.data,
id: data.id
})
} else {
resolve({
jsonrpc: '2.0',
error,
id: data.id
})
}
}
return resolve(response)
})
})
} else {
const message = await provider.request(data)
return {jsonrpc: '2.0', result: message, id: data.id}
try {
const message = await provider.request(data)
return {jsonrpc: '2.0', result: message, id: data.id}
} catch (e) {
return {jsonrpc: '2.0', error: { message: e.message, code: -32603 }, id: data.id}
}
}
}
} else {
console.error(
`Cannot make ${data.method} request. Remix client is not connected to walletconnect client`
)
return {jsonrpc: '2.0', result: [], id: data.id}
const err = `Cannot make ${data.method} request. Remix client is not connected to walletconnect client`
console.error(err)
return {jsonrpc: '2.0', error: { message: err, code: -32603 }, id: data.id}
}
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/ghaction-helper",
"version": "0.1.13",
"version": "0.1.16",
"description": "Solidity Tests GitHub Action Helper",
"main": "src/index.js",
"scripts": {
@ -19,18 +19,17 @@
},
"homepage": "https://github.com/ethereum/remix-project#readme",
"devDependencies": {
"@remix-project/remix-solidity": "^0.5.19",
"@remix-project/remix-solidity": "^0.5.22",
"@types/chai": "^4.3.4",
"typescript": "^4.9.3"
},
"dependencies": {
"@ethereum-waffle/chai": "^3.4.4",
"@remix-project/remix-simulator": "^0.2.33",
"@remix-project/remix-simulator": "^0.2.36",
"chai": "^4.3.7",
"ethers": "^5.7.2",
"web3": "^4.1.1"
},
"types": "./src/index.d.ts",
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220"
}
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1"
}

@ -11,12 +11,14 @@ const providerConfig = {
blockNumber: global.blockNumber || null
}
const config = { defaultTransactionType: '0x0' }
global.remixProvider = new Provider(providerConfig)
global.remixProvider.init()
global.web3Provider = new ethers.providers.Web3Provider(global.remixProvider)
global.provider = global.web3Provider
global.ethereum = global.web3Provider
global.web3 = new Web3(global.web3Provider)
global.web3.eth.setConfig(config)
const isFactoryOptions = (signerOrOptions: any) => {
if (!signerOrOptions || signerOrOptions === undefined || signerOrOptions instanceof ethers.Signer) return false

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-analyzer",
"version": "0.5.42",
"version": "0.5.45",
"description": "Tool to perform static analysis on Solidity smart contracts",
"scripts": {
"test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts"
@ -25,8 +25,8 @@
"@ethereumjs/tx": "^4.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethereumjs/vm": "^6.4.1",
"@remix-project/remix-astwalker": "^0.0.63",
"@remix-project/remix-lib": "^0.5.40",
"@remix-project/remix-astwalker": "^0.0.66",
"@remix-project/remix-lib": "^0.5.43",
"async": "^2.6.2",
"ethers": "^5.4.2",
"ethjs-util": "^0.1.6",
@ -50,6 +50,6 @@
"typescript": "^3.7.5"
},
"typings": "src/index.d.ts",
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220",
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1",
"main": "./src/index.js"
}
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-astwalker",
"version": "0.0.63",
"version": "0.0.66",
"description": "Tool to walk through Solidity AST",
"main": "src/index.js",
"scripts": {
@ -37,7 +37,7 @@
"@ethereumjs/tx": "^4.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethereumjs/vm": "^6.4.1",
"@remix-project/remix-lib": "^0.5.40",
"@remix-project/remix-lib": "^0.5.43",
"@types/tape": "^4.2.33",
"async": "^2.6.2",
"ethers": "^5.4.2",
@ -53,6 +53,6 @@
"tap-spec": "^5.0.0"
},
"typings": "src/index.d.ts",
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220",
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1",
"types": "./src/index.d.ts"
}
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-debug",
"version": "0.5.33",
"version": "0.5.36",
"description": "Tool to debug Ethereum transactions",
"contributors": [
{
@ -26,10 +26,10 @@
"@ethereumjs/tx": "^4.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethereumjs/vm": "^6.4.1",
"@remix-project/remix-astwalker": "^0.0.63",
"@remix-project/remix-lib": "^0.5.40",
"@remix-project/remix-simulator": "^0.2.33",
"@remix-project/remix-solidity": "^0.5.19",
"@remix-project/remix-astwalker": "^0.0.66",
"@remix-project/remix-lib": "^0.5.43",
"@remix-project/remix-simulator": "^0.2.36",
"@remix-project/remix-solidity": "^0.5.22",
"ansi-gray": "^0.1.1",
"async": "^2.6.2",
"color-support": "^1.1.3",
@ -69,6 +69,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme",
"typings": "src/index.d.ts",
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220",
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1",
"types": "./src/index.d.ts"
}
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-lib",
"version": "0.5.40",
"version": "0.5.43",
"description": "Library to various Remix tools",
"contributors": [
{
@ -19,10 +19,12 @@
"dependencies": {
"@ethereumjs/util": "^8.0.5",
"async": "^2.1.2",
"create-hash": "^1.2.0",
"ethers": "^5.7.2",
"ethjs-util": "^0.1.6",
"events": "^3.0.0",
"from-exponential": "1.1.1",
"rlp": "^3.0.0",
"solc": "^0.7.4",
"string-similarity": "^4.0.4",
"web3": "^4.1.1",
@ -53,6 +55,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme",
"typings": "src/index.d.ts",
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220",
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1",
"types": "./src/index.d.ts"
}
}

@ -14,10 +14,10 @@ export function encodeParams (funABI, args) {
if (funABI.inputs && funABI.inputs.length) {
for (let i = 0; i < funABI.inputs.length; i++) {
const type = funABI.inputs[i].type
// "false" will be converting to `false` and "true" will be working
// fine as abiCoder assume anything in quotes as `true`
if (type === 'bool' && args[i] === 'false') {
args[i] = false
if (type === 'bool') {
if (args[i] === false || args[i] === 'false' || args[i] === '0' || args[i] === 0) args[i] = false
else if (args[i] === true || args[i] === 'true' || args[i] === '1' || args[i] === 1) args[i] = true
else throw new Error(`provided value for boolean is invalid: ${args[i]}`)
}
types.push(type.indexOf('tuple') === 0 ? makeFullTypeDefinition(funABI.inputs[i]) : type)
if (args.length < types.length) {

@ -23,7 +23,7 @@ export class TxRunnerWeb3 {
// this is to avoid the following issue: https://github.com/MetaMask/metamask-extension/issues/11824
tx.type = '0x2'
} else {
tx.type = '0x1'
// tx.type = '0x1'
}
if (txFee) {
if (txFee.baseFeePerGas) {
@ -81,7 +81,7 @@ export class TxRunnerWeb3 {
)
} else {
try {
const res = await this.getWeb3().eth.sendTransaction(tx)
const res = await this.getWeb3().eth.sendTransaction(tx, null, { checkRevertBeforeSending: false })
cb(null, res.transactionHash)
} catch (e) {
console.log(`Send transaction failed: ${e.message} . if you use an injected provider, please check it is properly unlocked. `)
@ -175,16 +175,22 @@ export class TxRunnerWeb3 {
}
}
async function tryTillReceiptAvailable (txhash, web3) {
async function tryTillReceiptAvailable (txhash: string, web3: Web3) {
try {
const receipt = await web3.eth.getTransactionReceipt(txhash)
if (receipt) return receipt
if (receipt) {
if (!receipt.to && !receipt.contractAddress) {
// this is a contract creation and the receipt doesn't contain a contract address. we have to keep polling...
console.log('this is a contract creation and the receipt does nott contain a contract address. we have to keep polling...')
} else
return receipt
}
} catch (e) {}
await pause()
return await tryTillReceiptAvailable(txhash, web3)
}
async function tryTillTxAvailable (txhash, web3) {
async function tryTillTxAvailable (txhash: string, web3: Web3) {
try {
const tx = await web3.eth.getTransaction(txhash)
if (tx && tx.blockHash) return tx

@ -158,7 +158,7 @@ export const ripemd160FromArray = function(a: number[], padded: boolean): Buffer
* @param a The input data
*/
export const rlphash = function(a: Input): Buffer {
return keccak(encode(a))
return keccak(Buffer.from(encode(a)))
}
/**

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-simulator",
"version": "0.2.33",
"version": "0.2.36",
"description": "Ethereum IDE and tools for the web",
"contributors": [
{
@ -22,7 +22,7 @@
"@ethereumjs/tx": "^4.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethereumjs/vm": "^6.4.1",
"@remix-project/remix-lib": "^0.5.40",
"@remix-project/remix-lib": "^0.5.43",
"ansi-gray": "^0.1.1",
"async": "^3.1.0",
"body-parser": "^1.18.2",
@ -34,6 +34,7 @@
"express": "^4.16.3",
"express-ws": "^4.0.0",
"merge": "^1.2.0",
"rlp": "^3.0.0",
"string-similarity": "^4.0.4",
"time-stamp": "^2.0.0",
"web3": "^4.1.1",
@ -68,6 +69,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme",
"typings": "src/index.d.ts",
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220",
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1",
"types": "./src/index.d.ts"
}
}

@ -158,7 +158,10 @@ export class Transactions {
this.vmContext.web3().flagNextAsDoNotRecordEvmSteps()
processTx(this.txRunnerInstance, payload, true, (error, value: VMexecutionResult) => {
if (error) return cb(error)
const result: RunTxResult = value.result
const result: any = value.result
if (result.execResult && result.execResult.exceptionError && result.execResult.exceptionError.errorType === 'EvmError') {
return cb(result.execResult.exceptionError.error)
}
if ((result as any).receipt?.status === '0x0' || (result as any).receipt?.status === 0) {
try {
const msg = `0x${result.execResult.returnValue.toString('hex') || '0'}`

@ -71,7 +71,7 @@ class StateManagerCommonStorageDump extends DefaultStateManager {
const stream = trie.createReadStream()
stream.on('data', (val) => {
const value = decode(val.value)
const value: any = decode(val.value)
storage['0x' + val.key.toString('hex')] = {
key: this.keyHashes[val.key.toString('hex')],
value: '0x' + value.toString('hex')

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-solidity",
"version": "0.5.19",
"version": "0.5.22",
"description": "Tool to load and run Solidity compiler",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -19,7 +19,7 @@
"@ethereumjs/tx": "^4.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethereumjs/vm": "^6.4.1",
"@remix-project/remix-lib": "^0.5.40",
"@remix-project/remix-lib": "^0.5.43",
"async": "^2.6.2",
"eslint-scope": "^5.0.0",
"ethers": "^5.4.2",
@ -57,5 +57,5 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme",
"typings": "src/index.d.ts",
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220"
}
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-tests",
"version": "0.2.33",
"version": "0.2.36",
"description": "Tool to test Solidity smart contracts",
"main": "src/index.js",
"types": "./src/index.d.ts",
@ -41,9 +41,9 @@
"@ethereumjs/tx": "^4.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethereumjs/vm": "^6.4.1",
"@remix-project/remix-lib": "^0.5.40",
"@remix-project/remix-simulator": "^0.2.33",
"@remix-project/remix-solidity": "^0.5.19",
"@remix-project/remix-lib": "^0.5.43",
"@remix-project/remix-simulator": "^0.2.36",
"@remix-project/remix-solidity": "^0.5.22",
"@remix-project/remix-url-resolver": "^0.0.42",
"ansi-gray": "^0.1.1",
"async": "^2.6.0",
@ -78,5 +78,5 @@
"typescript": "^3.3.1"
},
"typings": "src/index.d.ts",
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220"
}
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1"
}

@ -1,5 +1,5 @@
export { default as RemixApp } from './lib/remix-app/remix-app'
export { dispatchModalContext, dispatchModalInterface, AppContext } from './lib/remix-app/context/context'
export { dispatchModalContext, dispatchModalInterface, AppContext, appProviderContextType, appPlatformTypes } from './lib/remix-app/context/context'
export { ModalProvider, useDialogDispatchers } from './lib/remix-app/context/provider'
export { AppModal } from './lib/remix-app/interface/index'
export { AlertModal } from './lib/remix-app/interface/index'

@ -1,7 +1,6 @@
import React from 'react'
import {AlertModal, AppModal} from '../interface'
import {ModalInitialState} from '../state/modals'
import { Plugin } from '@remixproject/engine'
export type appProviderContextType = {
settings: any,
@ -9,10 +8,13 @@ export type appProviderContextType = {
appManager: any
modal: any
layout: any
platform: appPlatformType
platform: appPlatformTypes
}
export type appPlatformType = 'web' | 'desktop'
export enum appPlatformTypes {
web = 'web',
desktop = 'desktop'
}
export const AppContext = React.createContext<appProviderContextType>(null)

@ -7,7 +7,7 @@ import Carousel from 'react-multi-carousel'
import WorkspaceTemplate from './workspaceTemplate'
import 'react-multi-carousel/lib/styles.css'
import CustomNavButtons from './customNavButtons'
import isElectron from 'is-electron'
import { AppContext, appPlatformTypes } from '@remix-ui/app'
declare global {
interface Window {
_paq: any
@ -19,6 +19,7 @@ interface HomeTabGetStartedProps {
}
function HomeTabGetStarted({plugin}: HomeTabGetStartedProps) {
const {platform} = useContext(AppContext)
const themeFilter = useContext(ThemeContext)
const carouselRef = useRef<any>({})
const carouselRefDiv = useRef(null)
@ -59,7 +60,7 @@ function HomeTabGetStarted({plugin}: HomeTabGetStartedProps) {
}
const createWorkspace = async (templateName) => {
if(isElectron()){
if(platform === appPlatformTypes.desktop){
await plugin.call('remix-templates', 'loadTemplateInNewWindow', templateName)
return
}

@ -26,14 +26,14 @@ export function LanguageOptions({ plugin }: { plugin: any }) {
return (
<>
<div className={langOptions !== 'fr' ? `d-flex align-items-center justify-content-end mr-2` : `d-flex align-items-center justify-content-end mr-3`}>
<div style={{position: 'absolute', right: "1rem", paddingTop: "0.4rem"}}>
<Dropdown>
<Dropdown.Toggle title={langOptions} id="languagedropdown" size="sm">
<Dropdown.Toggle title={langOptions} id="languagedropdown" size="sm" style={{backgroundColor: 'var(--secondary)'}}>
{langOptions}
</Dropdown.Toggle>
<Dropdown.Menu className="dropdown-menu langSelector" style={{ minWidth: '2rem', backgroundColor: 'var(--body-bg)'}}>
<Dropdown.Menu className="dropdown-menu langSelector" style={{ paddingTop: "0px", paddingBottom: "0px", minWidth: 'fit-content', backgroundColor: 'var(--body-bg)'}}>
{['EN', 'ES', 'FR', 'IT', 'ZH'].map((lang, index) => (
<DropdownItem as={'span'} className="p-2" onClick={() =>
<DropdownItem as={'span'} className={langOptions === lang ? "border border-primary px-2" : "px-2"} onClick={() =>
{
changeLanguage(lang.toLowerCase())
setLangOptions(lang)

@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react' // eslint-disable-line
import React, {useState, useEffect, useContext} from 'react' // eslint-disable-line
import './remix-ui-home-tab.css'
import {ThemeContext, themes} from './themeContext'
@ -9,7 +9,7 @@ import HomeTabScamAlert from './components/homeTabScamAlert'
import HomeTabGetStarted from './components/homeTabGetStarted'
import HomeTabFeatured from './components/homeTabFeatured'
import HomeTabFeaturedPlugins from './components/homeTabFeaturedPlugins'
import isElectron from 'is-electron'
import { AppContext, appPlatformTypes } from '@remix-ui/app'
import { HomeTabFileElectron } from './components/homeTabFileElectron'
import { LanguageOptions } from './components/homeTablangOptions'
@ -24,6 +24,7 @@ export interface RemixUiHomeTabProps {
}
export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => {
const {platform} = useContext(AppContext)
const {plugin} = props
const [state, setState] = useState<{
@ -59,7 +60,7 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => {
<div className="d-flex flex-row w-100 custom_home_bg">
<div className="px-2 pl-3 justify-content-start d-flex border-right flex-column" id="remixUIHTLeft" style={{width: 'inherit'}}>
<HomeTabTitle />
{!isElectron()?
{!(platform === appPlatformTypes.desktop) ?
<HomeTabFile plugin={plugin} />:
<HomeTabFileElectron plugin={plugin}></HomeTabFileElectron>}
<HomeTabLearn plugin={plugin} />

@ -1,9 +1,9 @@
/* eslint-disable no-unused-expressions */
import isElectron from 'is-electron'
import React, {useContext, useEffect, useRef, useState} from 'react' // eslint-disable-line
import DragBar from '../dragbar/dragbar'
import RemixUIPanelPlugin from '../plugins/panel-plugin'
import {PluginRecord} from '../types'
import { AppContext, appPlatformTypes } from '@remix-ui/app'
import './main-panel.css'
@ -12,6 +12,7 @@ export type RemixUIMainPanelProps = {
}
const RemixUIMainPanel = (props: RemixUIMainPanelProps) => {
const {platform} = useContext(AppContext)
const appContext = useContext(props.Context)
const [plugins, setPlugins] = useState<PluginRecord[]>([])
const editorRef = useRef<HTMLDivElement>(null)
@ -29,7 +30,7 @@ const RemixUIMainPanel = (props: RemixUIMainPanelProps) => {
profile: panel.plugin.profile,
active: panel.active,
view: panel.plugin.profile.name === 'tabs' ? panel.plugin.renderTabsbar() : panel.plugin.render(),
class: panel.plugin.profile.name + '-wrap ' + (panel.minimized ? 'minimized ' : ' ') + (isElectron()? 'desktop' : ''),
class: panel.plugin.profile.name + '-wrap ' + (panel.minimized ? 'minimized ' : ' ') + ((platform === appPlatformTypes.desktop)? 'desktop' : ''),
minimized: panel.minimized
})
})

@ -26,9 +26,8 @@ export function MainnetPrompt(props: MainnetProps) {
const onMaxFeeChange = (value: string) => {
const maxFee = value
// @ts-ignore
if (toBN(props.network.lastBlock.baseFeePerGas).gt(toBN(toWei(maxFee, 'Gwei')))) {
setTransactionFee(intl.formatMessage({id: 'udapp.transactionFeeText'}))
if (toBigInt(props.network.lastBlock.baseFeePerGas) > toBigInt(toWei(maxFee, 'Gwei'))) {
setTransactionFee(intl.formatMessage({id: 'udapp.transactionFee'}))
props.updateGasPriceStatus(false)
props.updateConfirmSettings(true)
return

@ -1,12 +1,12 @@
import { EOL } from 'os'
import { SearchResultLineLine } from '../../types'
import isElectron from 'is-electron'
import Registry from 'apps/remix-ide/src/app/state/registry'
export const getDirectory = async (dir: string, plugin: any) => {
let result = []
if (isElectron()) {
if (Registry.getInstance().get('platform').api.isDesktop()) {
const files = await plugin.call('ripgrep', 'glob', dir, '**/*')
// only get path property of files

@ -345,6 +345,8 @@ export const CompilerApiMixin = (Base) => class extends Base {
if(await this.getAppParameter('hardhat-compilation')) this.compileTabLogic.runCompiler('hardhat')
else if(await this.getAppParameter('truffle-compilation')) this.compileTabLogic.runCompiler('truffle')
else this.compileTabLogic.runCompiler(undefined)
} else if (this.currentFile && this.currentFile.endsWith('.circom')) {
await this.call('circuit-compiler', 'compile', this.currentFile)
}
}
}

@ -1,4 +1,4 @@
import React, {useEffect, useState, useRef, useReducer} from 'react' // eslint-disable-line
import React, {useEffect, useState, useRef, useReducer, useContext} from 'react' // eslint-disable-line
import {FormattedMessage, useIntl} from 'react-intl'
import semver from 'semver'
import {CompilerContainerProps} from './types'
@ -11,9 +11,9 @@ import {getValidLanguage} from '@remix-project/remix-solidity'
import {CopyToClipboard} from '@remix-ui/clipboard'
import {configFileContent} from './compilerConfiguration'
import axios, {AxiosResponse} from 'axios'
import { AppContext, appPlatformTypes } from '@remix-ui/app'
import './css/style.css'
import isElectron from 'is-electron'
import { Dropdown } from 'react-bootstrap'
const defaultPath = 'compiler_config.json'
@ -26,6 +26,7 @@ declare global {
const _paq = (window._paq = window._paq || []) //eslint-disable-line
export const CompilerContainer = (props: CompilerContainerProps) => {
const {platform} = useContext(AppContext)
const {
api,
compileTabLogic,
@ -577,7 +578,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
// "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium,
// resort to non-worker version in that case.
if (selectedVersion === 'builtin') selectedVersion = state.defaultVersion
if (selectedVersion !== 'builtin' && (canUseWorker(selectedVersion) || isElectron())) {
if (selectedVersion !== 'builtin' && (canUseWorker(selectedVersion) || platform === appPlatformTypes.desktop)) {
compileTabLogic.compiler.loadVersion(true, url)
} else {
compileTabLogic.compiler.loadVersion(false, url)

@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect, ReactElement } from 'react' // eslint-disable-line
import React, { useState, useRef, useEffect, ReactElement, useContext } from 'react' // eslint-disable-line
import { FormattedMessage, useIntl } from 'react-intl'
import * as semver from 'semver'
import { eachOfSeries } from 'async' // eslint-disable-line
@ -9,7 +9,7 @@ import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
import { format } from 'util'
import './css/style.css'
import { CustomTooltip } from '@remix-ui/helper'
import isElectron from 'is-electron'
import { AppContext, appPlatformTypes } from '@remix-ui/app'
const _paq = ((window as any)._paq = (window as any)._paq || []) // eslint-disable-line @typescript-eslint/no-explicit-any
@ -44,7 +44,7 @@ interface FinalResult {
export const SolidityUnitTesting = (props: Record<string, any>) => {
// eslint-disable-line @typescript-eslint/no-explicit-any
const {platform} = useContext(AppContext)
const { helper, testTab, initialPath } = props
const { testTabLogic } = testTab
@ -608,7 +608,7 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
currentCompilerUrl,
evmVersion,
optimize,
usingWorker: canUseWorker(currentVersion) || isElectron(),
usingWorker: canUseWorker(currentVersion) || platform === appPlatformTypes.desktop,
runs,
}
const deployCb = async (file: string, contractAddress: string) => {

@ -47,7 +47,7 @@ const Context = ({opts, provider}: {opts; provider: string}) => {
<div>
<span>
<span className="remix_ui_terminal_tx">
[block:{block} txIndex:{i}]
[block:{block.toString()} txIndex:{i.toString()}]
</span>
<div className="remix_ui_terminal_txItem">
<span className="remix_ui_terminal_txItemTitle">from:</span> {from}
@ -76,7 +76,7 @@ const Context = ({opts, provider}: {opts; provider: string}) => {
<div>
<span>
<span className="remix_ui_terminal_tx">
[block:{block} txIndex:{i}]
[block:{block.toString()} txIndex:{i.toString()}]
</span>
<div className="remix_ui_terminal_txItem">
<span className="remix_ui_terminal_txItemTitle">from:</span> {from}

@ -75,8 +75,8 @@ const showTable = (opts, showTableHash) => {
<FormattedMessage id="terminal.blockNumber" />
</td>
<td className="remix_ui_terminal_td" data-id={`txLoggerTableContractAddress${opts.hash}`} data-shared={`pair_${opts.hash}`}>
{opts.blockNumber}
<CopyToClipboard content={opts.blockNumber} />
{opts.blockNumber.toString()}
<CopyToClipboard content={opts.blockNumber.toString()} />
</td>
</tr>
) : null}

@ -8,8 +8,8 @@ import { createWorkspaceTemplate, getWorkspaces, loadWorkspacePreset, setPlugin,
import { QueryParams } from '@remix-project/remix-lib'
import { fetchContractFromEtherscan } from '@remix-project/core-plugin' // eslint-disable-line
import JSZip from 'jszip'
import isElectron from 'is-electron'
import { Actions, FileTree } from '../types'
import Registry from 'apps/remix-ide/src/app/state/registry'
export * from './events'
export * from './workspace'
@ -55,7 +55,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
const electrOnProvider = filePanelPlugin.fileProviders.electron
const params = queryParams.get() as UrlParametersType
let workspaces = []
if (!isElectron()) {
if (!(Registry.getInstance().get('platform').api.isDesktop())) {
workspaces = await getWorkspaces() || []
dispatch(setWorkspaces(workspaces))
}
@ -118,7 +118,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
await basicWorkspaceInit(workspaces, workspaceProvider)
}
} else await basicWorkspaceInit(workspaces, workspaceProvider)
} else if (isElectron()) {
} else if (Registry.getInstance().get('platform').api.isDesktop()) {
if (params.opendir) {
params.opendir = decodeURIComponent(params.opendir)
plugin.call('notification', 'toast', `opening ${params.opendir}...`)
@ -154,7 +154,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
listenOnProviderEvents(workspaceProvider)(dispatch)
listenOnProviderEvents(localhostProvider)(dispatch)
listenOnProviderEvents(electrOnProvider)(dispatch)
if (isElectron()) {
if (Registry.getInstance().get('platform').api.isDesktop()) {
dispatch(setMode('browser'))
} else {
dispatch(setMode('browser'))

@ -38,7 +38,6 @@ import { IndexedDBStorage } from '../../../../../../apps/remix-ide/src/app/files
import { getUncommittedFiles } from '../utils/gitStatusFilter'
import { AppModal, ModalTypes } from '@remix-ui/app'
import { contractDeployerScripts, etherscanScripts } from '@remix-project/remix-ws-templates'
import isElectron from 'is-electron'
declare global {
interface Window {
@ -120,7 +119,7 @@ export const createWorkspace = async (
isGitRepo: boolean = false,
createCommit: boolean = true
) => {
if (isElectron()) {
if (plugin.registry.get('platform').api.isDesktop()) {
if (workspaceTemplateName) {
await plugin.call('remix-templates', 'loadTemplateInNewWindow', workspaceTemplateName, opts)
}
@ -577,7 +576,7 @@ export const cloneRepository = async (url: string) => {
const token = config.get('settings/gist-access-token')
const repoConfig = { url, token }
if (isElectron()) {
if (plugin.registry.get('platform').api.isDesktop()) {
try {
await plugin.call('dGitProvider', 'clone', repoConfig)
} catch (e) {

@ -1,15 +1,16 @@
import React, { MouseEventHandler, useContext, useEffect, useState } from "react"
import { FileSystemContext } from "../contexts"
import isElectron from 'is-electron'
import { AppContext, appPlatformTypes } from '@remix-ui/app'
import { FormattedMessage } from "react-intl"
import '../css/electron-menu.css'
import { CustomTooltip } from '@remix-ui/helper'
export const ElectronMenu = () => {
const {platform} = useContext(AppContext)
const global = useContext(FileSystemContext)
useEffect(() => {
if (isElectron()) {
if (platform === appPlatformTypes.desktop) {
global.dispatchGetElectronRecentFolders()
}
}, [])
@ -24,7 +25,7 @@ export const ElectronMenu = () => {
}
return (
!isElectron() ? null :
(platform !== appPlatformTypes.desktop) ? null :
(global.fs.browser.isSuccessfulWorkspace ? null :
<>
<div onClick={async () => { await openFolderElectron(null) }} className='btn btn-primary'><FormattedMessage id="electron.openFolder" /></div>

@ -1,11 +1,11 @@
import React, {useRef, useEffect, useState} from 'react' // eslint-disable-line
import React, {useRef, useEffect, useState, useContext} from 'react' // eslint-disable-line
import {useIntl} from 'react-intl'
import {action, FileExplorerContextMenuProps} from '../types'
import '../css/file-explorer-context-menu.css'
import {customAction} from '@remixproject/plugin-api'
import UploadFile from './upload-file'
import isElectron from 'is-electron'
import { AppContext, appPlatformTypes } from '@remix-ui/app'
declare global {
interface Window {
@ -15,6 +15,7 @@ declare global {
const _paq = (window._paq = window._paq || []) //eslint-disable-line
export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => {
const {platform} = useContext(AppContext)
const {
actions,
createNewFile,
@ -83,7 +84,7 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) =>
}
const itemMatchesCondition = (item: action, itemType: string, itemPath: string) => {
if( isElectron() && item.platform && item.platform === 'browser') return false
if( platform === appPlatformTypes.desktop && item.platform && item.platform === appPlatformTypes.web) return false
else if (item.type && Array.isArray(item.type) && (item.type.findIndex(name => name === itemType) !== -1)) return true
else if (item.path && Array.isArray(item.path) && (item.path.findIndex(key => key === itemPath) !== -1)) return true
else if (item.extension && Array.isArray(item.extension) && (item.extension.findIndex(ext => itemPath.endsWith(ext)) !== -1)) return true

@ -2,8 +2,7 @@ import React, { useContext } from 'react'
import {CustomTooltip, CustomMenu, CustomIconsToggle} from '@remix-ui/helper'
import {Dropdown, NavDropdown} from 'react-bootstrap'
import {FormattedMessage} from 'react-intl'
import { AppContext, appPlatformType } from 'libs/remix-ui/app/src/lib/remix-app/context/context'
import { AppContext, appPlatformTypes } from '@remix-ui/app'
const _paq = (window._paq = window._paq || [])
export interface HamburgerMenuItemProps {
@ -11,7 +10,7 @@ export interface HamburgerMenuItemProps {
kind: string
actionOnClick: () => void
fa: string
platforms: appPlatformType[]
platforms: appPlatformTypes[]
}
export function HamburgerMenuItem(props: HamburgerMenuItemProps) {
@ -73,7 +72,7 @@ export interface HamburgerSubMenuItemProps {
id: string
title: string
subMenus: Array<HamburgerMenuItemProps>
platforms: appPlatformType[]
platforms: appPlatformTypes[]
}
export function HamburgerSubMenuItem(props: HamburgerSubMenuItemProps) {

@ -1,3 +1,4 @@
import { appPlatformTypes } from 'libs/remix-ui/app/src/lib/remix-app/context/context'
import React from 'react'
import {Dropdown} from 'react-bootstrap'
import {HamburgerMenuItem, HamburgerSubMenuItem} from './workspace-hamburger-item'
@ -33,7 +34,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.createWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web', 'desktop']}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="clone"
@ -43,7 +44,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.cloneGitRepository()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web', 'desktop']}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="rename"
@ -53,7 +54,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.renameCurrentWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web']}
platforms={[appPlatformTypes.web]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="download"
@ -63,7 +64,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.downloadCurrentWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web']}
platforms={[appPlatformTypes.web]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="delete"
@ -73,7 +74,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.deleteCurrentWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web']}
platforms={[appPlatformTypes.web]}
></HamburgerMenuItem>
<Dropdown.Divider className="border mb-0 mt-0 remixui_menuhr" style={{pointerEvents: 'none'}} />
<HamburgerMenuItem
@ -84,7 +85,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.deleteAllWorkspaces()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web']}
platforms={[appPlatformTypes.web]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="backup"
@ -94,7 +95,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.downloadWorkspaces()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web']}
platforms={[appPlatformTypes.web]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="restore"
@ -104,7 +105,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.restoreBackup()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web']}
platforms={[appPlatformTypes.web]}
></HamburgerMenuItem>
<Dropdown.Divider className="border mt-0 mb-0 remixui_menuhr" style={{pointerEvents: 'none'}} />
<HamburgerMenuItem
@ -115,7 +116,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.addGithubAction()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web', 'desktop']}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="tssoltestghaction"
@ -125,7 +126,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.addTsSolTestGithubAction()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web', 'desktop']}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="slitherghaction"
@ -135,7 +136,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.addSlitherGithubAction()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web', 'desktop']}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<Dropdown.Divider className="border mb-0 mt-0 remixui_menuhr" style={{pointerEvents: 'none'}} />
<HamburgerMenuItem
@ -146,7 +147,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.addHelperScripts('etherscan')
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web', 'desktop']}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="addscriptdeployer"
@ -156,7 +157,7 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
props.addHelperScripts('deployer')
props.hideIconsMenu(!showIconsMenu)
}}
platforms={['web', 'desktop']}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
</>
)

@ -12,7 +12,7 @@ import {MenuItems, WorkSpaceState} from './types'
import {contextMenuActions} from './utils'
import FileExplorerContextMenu from './components/file-explorer-context-menu'
import { customAction } from '@remixproject/plugin-api'
import isElectron from 'is-electron'
import { AppContext, appPlatformTypes } from '@remix-ui/app'
import { ElectronMenu } from './components/electron-menu'
const _paq = (window._paq = window._paq || [])
@ -20,6 +20,7 @@ const _paq = (window._paq = window._paq || [])
const canUpload = window.File || window.FileReader || window.FileList || window.Blob
export function Workspace() {
const {platform} = useContext(AppContext)
const LOCALHOST = ' - connect to localhost - '
const NO_WORKSPACE = ' - none - '
const ELECTRON = 'electron'
@ -229,7 +230,6 @@ export function Workspace() {
}
const cloneGitRepository = () => {
console.log('clone from workspace modal')
global.modal(
intl.formatMessage({id: 'filePanel.workspace.clone'}),
cloneModalMessage(),
@ -935,7 +935,7 @@ export function Workspace() {
</span>
</div>
<div className='mx-2'>
{!isElectron() ? (
{(platform !== appPlatformTypes.desktop) ? (
<Dropdown id="workspacesSelect" data-id="workspacesSelect" onToggle={toggleDropdown} show={showDropdown}>
<Dropdown.Toggle
as={CustomToggle}

@ -4,8 +4,9 @@ import { customAction } from '@remixproject/plugin-api'
import { fileDecoration } from '@remix-ui/file-decorators'
import { RemixAppManager } from 'libs/remix-ui/plugin-manager/src/types'
import { ViewPlugin } from '@remixproject/engine-web'
import { appPlatformTypes } from '@remix-ui/app'
export type action = { name: string, type?: Array<WorkspaceElement>, path?: string[], extension?: string[], pattern?: string[], id: string, multiselect: boolean, label: string, sticky?: boolean, group: number, platform?: 'electron' | 'browser' }
export type action = { name: string, type?: Array<WorkspaceElement>, path?: string[], extension?: string[], pattern?: string[], id: string, multiselect: boolean, label: string, sticky?: boolean, group: number, platform?: appPlatformTypes }
export interface JSONStandardInput {
language: 'Solidity'
settings?: any

@ -1,3 +1,4 @@
import { appPlatformTypes } from '@remix-ui/app'
import { FileType } from '@remix-ui/file-decorators'
import { WorkspaceProps, MenuItems } from '../types'
@ -64,7 +65,7 @@ export const contextMenuActions: MenuItems = [{
multiselect: false,
label: '',
group: 2,
platform: 'browser'
platform: appPlatformTypes.web
}, {
id: 'run',
name: 'Run',
@ -79,7 +80,7 @@ export const contextMenuActions: MenuItems = [{
multiselect: false,
label: '',
group: 4,
platform: 'browser'
platform: appPlatformTypes.web
}, {
id: 'publishFolderToGist',
name: 'Publish folder to gist',
@ -87,7 +88,7 @@ export const contextMenuActions: MenuItems = [{
multiselect: false,
label: '',
group: 4,
platform: 'browser'
platform: appPlatformTypes.web
}, {
id: 'publishFileToGist',
name: 'Publish file to gist',
@ -95,7 +96,7 @@ export const contextMenuActions: MenuItems = [{
multiselect: false,
label: '',
group: 4,
platform: 'browser'
platform: appPlatformTypes.web
}, {
id: 'uploadFile',
name: 'Load a Local File',
@ -103,7 +104,7 @@ export const contextMenuActions: MenuItems = [{
multiselect: false,
label: 'Load a Local File',
group: 4,
platform: 'browser'
platform: appPlatformTypes.web
}, {
id: 'publishToGist',
name: 'Push changes to gist',
@ -111,7 +112,7 @@ export const contextMenuActions: MenuItems = [{
multiselect: false,
label: 'Publish all to Gist',
group: 4,
platform: 'browser'
platform: appPlatformTypes.web
},
{
id: 'publishWorkspace',
@ -120,7 +121,7 @@ export const contextMenuActions: MenuItems = [{
multiselect: false,
label: '',
group: 4,
platform: 'browser'
platform: appPlatformTypes.web
}]
export const fileKeySort = (children: FileType[]): string[] => {

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-url-resolver",
"version": "0.0.62",
"version": "0.0.65",
"description": "Solidity import url resolver engine",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -40,5 +40,5 @@
"typescript": "^3.1.6"
},
"typings": "src/index.d.ts",
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220"
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-ws-templates",
"version": "1.0.27",
"version": "1.0.30",
"description": "Create a Remix IDE workspace using different templates",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -24,5 +24,5 @@
"ethers": "^5.4.2",
"web3": "^4.1.1"
},
"gitHead": "b6db2a29c223e423c70f06b87d9b245e26f0b220"
}
"gitHead": "b8606fe2db170b6ef7cdd19b498db74cf2fb14b1"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remixd",
"version": "0.6.18",
"version": "0.6.19",
"description": "remix server: allow accessing file system from remix.ethereum.org and start a dev environment (see help section)",
"main": "index.js",
"types": "./index.d.ts",

@ -1,6 +1,6 @@
{
"name": "remix-project",
"version": "0.37.0-dev",
"version": "0.38.0-dev",
"license": "MIT",
"description": "Ethereum Remix Monorepo",
"main": "index.js",
@ -159,6 +159,7 @@
"commander": "^9.4.1",
"core-js": "^3.6.5",
"cors": "^2.8.5",
"create-hash": "^1.2.0",
"deep-equal": "^1.0.1",
"document-register-element": "1.13.1",
"electron-squirrel-startup": "^1.0.0",
@ -206,6 +207,7 @@
"react-tabs": "^3.2.2",
"react-zoom-pan-pinch": "^3.0.2",
"regenerator-runtime": "0.13.7",
"rlp": "^3.0.0",
"remark-gfm": "^3.0.1",
"rss-parser": "^3.12.0",
"signale": "^1.4.0",

Loading…
Cancel
Save