From f59d665bd48098d41aacfdbc17e26003344e1739 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Thu, 21 Jul 2022 14:02:17 +0530 Subject: [PATCH 01/69] remixd readme updated --- libs/remixd/README.md | 64 +++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/libs/remixd/README.md b/libs/remixd/README.md index 12726f5560..c0ed97a6a0 100644 --- a/libs/remixd/README.md +++ b/libs/remixd/README.md @@ -1,59 +1,83 @@ # Remixd -`remixd` is a tool that intend to be used with [Remix IDE](https://github.com/ethereum/remix-project) (aka. Browser-Solidity). It allows a websocket connection between -`Remix IDE` (web application) and the local computer. +`remixd` is an NPM module that intends to be used with [Remix IDE](https://remix.ethereum.org/) web and desktop applications. It establishes a two-way websocket connection between the local computer and Remix IDE for a particular project directory. -Practically Remix IDE makes available a folder shared by `remixd`. +`remixd` can be used to setup a development environment with other popular frameworks like Hardhat, Truffle, Slither etc. -More details are explained in this [tutorial](https://remix-ide.readthedocs.io/en/latest/remixd.html). +More details are explained in the [documentation](https://remix-ide.readthedocs.io/en/latest/remixd.html). -Alternatively `remixd` can be used to setup a development environment that can be used with other popular frameworks like Embark, Truffle, Ganache, etc.. +## Installation -`remixd` needs `npm` and `node` +`npm install -g @remix-project/remixd` -## INSTALLATION +NOTE: When the remixd NPM module is installed, it also installs [Slither](https://github.com/crytic/slither), [solc-select](https://github.com/crytic/solc-select#quickstart) and sets [solc](https://docs.soliditylang.org/en/latest/installing-solidity.html) to latest version i.e. 0.8.15 currently. -`yarn global add @remix-project/remixd` +ALSO NOTE: Python3.6+ (pip3) needs to already be installed on the System. In case of any discrepany, Slither can also installed along with other dependencies using command: +``` +> remixd -i slither +``` + +_(This packaging of Slither with the remixd module is supported since Remixd v0.6.3)_ -### Warning for old users +### Warning for quite old users There is a new version of remixd with a new npm address: https://npmjs.com/package/@remix-project/remixd If you were using the old one you need to: 1. uninstall the old one: `npm uninstall -g remixd` - 2. install the new: `yarn global add @remix-project/remixd` + 2. install the new: `npm install -g @remix-project/remixd` +## remixd command -## HELP SECTION +The remixd command without options shares present working directory and the shared Remix domain will be https://remix.ethereum.org, https://remix-alpha.ethereum.org, or https://remix-beta.ethereum.org +The remixd command is: +``` +> remixd ``` -Usage: remixd -s -Provide a two-way connection between the local computer and Remix IDE +If you are using Remix from localhost or you are not running the command from your working directory, you’ll need to use the command with flags. + +``` +> remixd -h +Usage: remixd [options] + +Establish a two-way websocket connection between the local computer and Remix IDE for a folder Options: -v, --version output the version number - -u, --remix-ide URL of remix instance allowed to connect to this web sockect connection - -s, --shared-folder Folder to share with Remix IDE + -u, --remix-ide URL of remix instance allowed to connect + -s, --shared-folder Folder to share with Remix IDE (Default: CWD) + -i, --install Module name to install locally (Supported: ["slither"]) -r, --read-only Treat shared folder as read-only (experimental) -h, --help output usage information Example: - remixd -s ./ -u http://localhost:8080 + remixd -s ./shared_project -u http://localhost:8080 ``` -## SHARE A FOLDER +## Share a project directory -`remixd -s --remix-ide https://remix.ethereum.org` +`remixd -s ./shared_project -u https://remix.ethereum.org` The current user should have `read/write` access to the folder (at least `read` access). It is important to notice that changes made to the current file in `Remix IDE` are automatically saved to the local computer every 5000 ms. There is no `Save` action. But the `Ctrl-Z` (undo) can be used. -Furthermore : +Furthermore: - No copy of the shared folder are kept in the browser storage. - - It is not possible to create a file from `Remix IDE` (that might change). + - Clicking on the new folder or new file icon under localhost will create a new file or folder in the shared folder. - If a folder does not contain any file, the folder will not be displayed in the explorer (that might change). - Symbolic links are not forwarded to Remix IDE. + +## Ports Usage +remixd creates a websocket connections with Remix IDE on different ports. Ports are defined according to specific purpose. Port usage details are as: + +- **65520** : For `remixd` websocket listener, to share a project from local device with Remix IDE. Shared folder will be loaded in the Remix IDE File Explorer workspace named localhost [See more](https://remix-ide.readthedocs.io/en/latest/remixd.html) +- **65522** : For `Hardhat` websocket listener, to enable the Hardhat Compilation using Remix IDE Solidity Compiler plugin, if shared folder is a Hardhat project [See more](https://remix-ide.readthedocs.io/en/latest/hardhat.html) +- **65523** : For `Slither` websocket listener, to enable the Slither Analysis using Remix IDE Solidity Static Analysis plugin [See more](https://remix-ide.readthedocs.io/en/latest/slither.html) +- **65524** : For `Truffle` websocket listener, to enable the Truffle Compilation using Remix IDE Solidity Compiler plugin, if shared folder is a Truffle project [See more](https://remix-ide.readthedocs.io/en/latest/truffle.html) + +Note: Please make sure your system is secured enough and these ports are not opened nor forwarded. From 2c2e64079b63e63339e71f2ce7b2c84d3f0f8d6c Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Thu, 21 Jul 2022 14:22:30 +0530 Subject: [PATCH 02/69] badges --- libs/remixd/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libs/remixd/README.md b/libs/remixd/README.md index c0ed97a6a0..bb563fe131 100644 --- a/libs/remixd/README.md +++ b/libs/remixd/README.md @@ -1,6 +1,11 @@ # Remixd -`remixd` is an NPM module that intends to be used with [Remix IDE](https://remix.ethereum.org/) web and desktop applications. It establishes a two-way websocket connection between the local computer and Remix IDE for a particular project directory. +[![npm version](https://badge.fury.io/js/%40remix-project%2Fremixd.svg)](https://www.npmjs.com/package/@remix-project/remixd) +[![npm](https://img.shields.io/npm/dt/@remix-project/remixd.svg?label=Total%20Downloads&logo=npm)](https://www.npmjs.com/package/@remix-project/remixd) +[![npm](https://img.shields.io/npm/dw/@remix-project/remixd.svg?logo=npm)](https://www.npmjs.com/package/@remix-project/remixd) + + +`@remix-project/remixd` is an NPM module that intends to be used with [Remix IDE](https://remix.ethereum.org/) web and desktop applications. It establishes a two-way websocket connection between the local computer and Remix IDE for a particular project directory. `remixd` can be used to setup a development environment with other popular frameworks like Hardhat, Truffle, Slither etc. From 23aa4fbd6aae74e4a7f11b6a3fe82b4f650d31d9 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Tue, 26 Jul 2022 19:09:01 +0530 Subject: [PATCH 03/69] save file with .yul extension if language is yul in URL --- libs/remix-ui/workspace/src/lib/actions/workspace.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 37533c87c6..221e0e1a09 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -75,7 +75,8 @@ export const createWorkspaceTemplate = async (workspaceName: string, template: W export type UrlParametersType = { gist: string, code: string, - url: string + url: string, + language: string } export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDefault') => { @@ -91,7 +92,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe if (params.code) { const hash = bufferToHex(keccakFromString(params.code)) - path = 'contract-' + hash.replace('0x', '').substring(0, 10) + '.sol' + path = 'contract-' + hash.replace('0x', '').substring(0, 10) + (params.language && params.language.toLowerCase() === 'yul' ? '.yul': '.sol') content = atob(params.code) await workspaceProvider.set(path, content) } From 3610439d0e684a52e67faa85affca268f499771d Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Tue, 26 Jul 2022 19:30:23 +0530 Subject: [PATCH 04/69] e2e added --- apps/remix-ide-e2e/src/tests/url.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apps/remix-ide-e2e/src/tests/url.test.ts b/apps/remix-ide-e2e/src/tests/url.test.ts index 00885338b4..2d7554215e 100644 --- a/apps/remix-ide-e2e/src/tests/url.test.ts +++ b/apps/remix-ide-e2e/src/tests/url.test.ts @@ -76,6 +76,22 @@ module.exports = { .openFile('ethereum/remix-project/apps/remix-ide/contracts/app/solidity/mode.sol') }, + 'Should load the code from language & code params': function (browser: NightwatchBrowser) { + browser + .pause(5000) + .url('http://127.0.0.1:8080/#language=yul&version=soljson-v0.8.7+commit.e28d00a7.js&code=Ly8gQSBjb250cmFjdCBjb25zaXN0cyBvZiBhIHNpbmdsZSBvYmplY3Qgd2l0aCBzdWItb2JqZWN0cyByZXByZXNlbnRpbmcKLy8gdGhlIGNvZGUgdG8gYmUgZGVwbG95ZWQgb3Igb3RoZXIgY29udHJhY3RzIGl0IGNhbiBjcmVhdGUuCi8vIFRoZSBzaW5nbGUgImNvZGUiIG5vZGUgaXMgdGhlIGV4ZWN1dGFibGUgY29kZSBvZiB0aGUgb2JqZWN0LgovLyBFdmVyeSAob3RoZXIpIG5hbWVkIG9iamVjdCBvciBkYXRhIHNlY3Rpb24gaXMgc2VyaWFsaXplZCBhbmQKLy8gbWFkZSBhY2Nlc3NpYmxlIHRvIHRoZSBzcGVjaWFsIGJ1aWx0LWluIGZ1bmN0aW9ucyBkYXRhY29weSAvIGRhdGFvZmZzZXQgLyBkYXRhc2l6ZQovLyBUaGUgY3VycmVudCBvYmplY3QsIHN1Yi1vYmplY3RzIGFuZCBkYXRhIGl0ZW1zIGluc2lkZSB0aGUgY3VycmVudCBvYmplY3QKLy8gYXJlIGluIHNjb3BlLgpvYmplY3QgIkNvbnRyYWN0MSIgewogICAgLy8gVGhpcyBpcyB0aGUgY29uc3RydWN0b3IgY29kZSBvZiB0aGUgY29udHJhY3QuCiAgICBjb2RlIHsKICAgICAgICBmdW5jdGlvbiBhbGxvY2F0ZShzaXplKSAtPiBwdHIgewogICAgICAgICAgICBwdHIgOj0gbWxvYWQoMHg0MCkKICAgICAgICAgICAgaWYgaXN6ZXJvKHB0cikgeyBwdHIgOj0gMHg2MCB9CiAgICAgICAgICAgIG1zdG9yZSgweDQwLCBhZGQocHRyLCBzaXplKSkKICAgICAgICB9CgogICAgICAgIC8vIGZpcnN0IGNyZWF0ZSAiQ29udHJhY3QyIgogICAgICAgIGxldCBzaXplIDo9IGRhdGFzaXplKCJDb250cmFjdDIiKQogICAgICAgIGxldCBvZmZzZXQgOj0gYWxsb2NhdGUoc2l6ZSkKICAgICAgICAvLyBUaGlzIHdpbGwgdHVybiBpbnRvIGNvZGVjb3B5IGZvciBFVk0KICAgICAgICBkYXRhY29weShvZmZzZXQsIGRhdGFvZmZzZXQoIkNvbnRyYWN0MiIpLCBzaXplKQogICAgICAgIC8vIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBpcyBhIHNpbmdsZSBudW1iZXIgMHgxMjM0CiAgICAgICAgbXN0b3JlKGFkZChvZmZzZXQsIHNpemUpLCAweDEyMzQpCiAgICAgICAgcG9wKGNyZWF0ZShvZmZzZXQsIGFkZChzaXplLCAzMiksIDApKQoKICAgICAgICAvLyBub3cgcmV0dXJuIHRoZSBydW50aW1lIG9iamVjdCAodGhlIGN1cnJlbnRseQogICAgICAgIC8vIGV4ZWN1dGluZyBjb2RlIGlzIHRoZSBjb25zdHJ1Y3RvciBjb2RlKQogICAgICAgIHNpemUgOj0gZGF0YXNpemUoIkNvbnRyYWN0MV9kZXBsb3llZCIpCiAgICAgICAgb2Zmc2V0IDo9IGFsbG9jYXRlKHNpemUpCiAgICAgICAgLy8gVGhpcyB3aWxsIHR1cm4gaW50byBhIG1lbW9yeS0+bWVtb3J5IGNvcHkgZm9yIEV3YXNtIGFuZAogICAgICAgIC8vIGEgY29kZWNvcHkgZm9yIEVWTQogICAgICAgIGRhdGFjb3B5KG9mZnNldCwgZGF0YW9mZnNldCgiQ29udHJhY3QxX2RlcGxveWVkIiksIHNpemUpCiAgICAgICAgcmV0dXJuKG9mZnNldCwgc2l6ZSkKICAgIH0KCiAgICBkYXRhICJUYWJsZTIiIGhleCI0MTIzIgoKICAgIG9iamVjdCAiQ29udHJhY3QxX2RlcGxveWVkIiB7CiAgICAgICAgY29kZSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGFsbG9jYXRlKHNpemUpIC0+IHB0ciB7CiAgICAgICAgICAgICAgICBwdHIgOj0gbWxvYWQoMHg0MCkKICAgICAgICAgICAgICAgIGlmIGlzemVybyhwdHIpIHsgcHRyIDo9IDB4NjAgfQogICAgICAgICAgICAgICAgbXN0b3JlKDB4NDAsIGFkZChwdHIsIHNpemUpKQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBydW50aW1lIGNvZGUKCiAgICAgICAgICAgIG1zdG9yZSgwLCAiSGVsbG8sIFdvcmxkISIpCiAgICAgICAgICAgIHJldHVybigwLCAweDIwKQogICAgICAgIH0KICAgIH0KCiAgICAvLyBFbWJlZGRlZCBvYmplY3QuIFVzZSBjYXNlIGlzIHRoYXQgdGhlIG91dHNpZGUgaXMgYSBmYWN0b3J5IGNvbnRyYWN0LAogICAgLy8gYW5kIENvbnRyYWN0MiBpcyB0aGUgY29kZSB0byBiZSBjcmVhdGVkIGJ5IHRoZSBmYWN0b3J5CiAgICBvYmplY3QgIkNvbnRyYWN0MiIgewogICAgICAgIGNvZGUgewogICAgICAgICAgICAvLyBjb2RlIGhlcmUgLi4uCiAgICAgICAgfQoKICAgICAgICBvYmplY3QgIkNvbnRyYWN0Ml9kZXBsb3llZCIgewogICAgICAgICAgICBjb2RlIHsKICAgICAgICAgICAgICAgIC8vIGNvZGUgaGVyZSAuLi4KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZGF0YSAiVGFibGUxIiBoZXgiNDEyMyIKICAgIH0KfQ&optimize=false&runs=200&evmVersion=null') + .refresh() + .pause(5000) + .clickLaunchIcon('filePanel') + .currentWorkspaceIs('code-sample') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontract-eaa022e37e.yul"]', 6000) + .openFile('contract-eaa022e37e.yul') + .getEditorValue((content) => { + browser.assert.ok(content && content.indexOf( + 'object "Contract1" {') !== -1) + }) + }, + 'Should load using URL compiler params': function (browser: NightwatchBrowser) { browser .pause(5000) From 2c95f7b7995883ce66daa09397d26d5c073a322e Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Tue, 26 Jul 2022 14:15:24 +0530 Subject: [PATCH 05/69] allow yul deployment --- libs/remix-core-plugin/src/lib/compiler-metadata.ts | 2 +- libs/remix-core-plugin/src/lib/editor-context-listener.ts | 2 +- libs/remix-ui/run-tab/src/lib/actions/events.ts | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libs/remix-core-plugin/src/lib/compiler-metadata.ts b/libs/remix-core-plugin/src/lib/compiler-metadata.ts index 2f065e769f..9a69e616f4 100644 --- a/libs/remix-core-plugin/src/lib/compiler-metadata.ts +++ b/libs/remix-core-plugin/src/lib/compiler-metadata.ts @@ -87,7 +87,7 @@ export class CompilerMetadata extends Plugin { let parsedMetadata try { - parsedMetadata = JSON.parse(contract.object.metadata) + parsedMetadata = contract.object && contract.object.metadata ? JSON.parse(contract.object.metadata) : null } catch (e) { console.log(e) } diff --git a/libs/remix-core-plugin/src/lib/editor-context-listener.ts b/libs/remix-core-plugin/src/lib/editor-context-listener.ts index 6fd5674e8a..3785c8ffd1 100644 --- a/libs/remix-core-plugin/src/lib/editor-context-listener.ts +++ b/libs/remix-core-plugin/src/lib/editor-context-listener.ts @@ -92,7 +92,7 @@ export class EditorContextListener extends Plugin { this._stopHighlighting() this.currentPosition = cursorPosition this.currentFile = file - if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) { + if (compilationResult && compilationResult.data && compilationResult.data.sources && compilationResult.data.sources[file]) { const nodes = sourceMappingDecoder.nodesAtPosition(null, cursorPosition, compilationResult.data.sources[file]) this.nodes = nodes if (nodes && nodes.length && nodes[nodes.length - 1]) { diff --git a/libs/remix-ui/run-tab/src/lib/actions/events.ts b/libs/remix-ui/run-tab/src/lib/actions/events.ts index 4355f4e87e..e47724aef0 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/events.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/events.ts @@ -95,7 +95,6 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch) => { const broadcastCompilationResult = async (plugin: RunTab, dispatch: React.Dispatch, file, source, languageVersion, data, input?) => { // TODO check whether the tab is configured const compiler = new CompilerAbstract(languageVersion, data, source, input) - plugin.compilersArtefacts[languageVersion] = compiler plugin.compilersArtefacts.__last = compiler @@ -103,9 +102,8 @@ const broadcastCompilationResult = async (plugin: RunTab, dispatch: React.Dispat return { name: languageVersion, alias: contract.name, file: contract.file, compiler } }) const index = contracts.findIndex(contract => contract.alias === plugin.REACT_API.contracts.currentContract) - if ((index < 0) && (contracts.length > 0)) dispatch(setCurrentContract(contracts[0].alias)) - const isUpgradeable = await plugin.call('openzeppelin-proxy', 'isConcerned', data.sources[file] ? data.sources[file].ast : {}) + const isUpgradeable = await plugin.call('openzeppelin-proxy', 'isConcerned', data.sources && data.sources[file] ? data.sources[file].ast : {}) if (isUpgradeable) { const options = await plugin.call('openzeppelin-proxy', 'getProxyOptions', data, file) From 7f2f74dffc3cc31c67bae531af9a329419a80ff7 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Tue, 26 Jul 2022 18:50:39 +0530 Subject: [PATCH 06/69] e2e tests added --- apps/remix-ide-e2e/src/tests/ballot.test.ts | 36 +++++++++++++++++++ .../src/lib/compiler-container.tsx | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/ballot.test.ts b/apps/remix-ide-e2e/src/tests/ballot.test.ts index 1c8383f047..04fd37077f 100644 --- a/apps/remix-ide-e2e/src/tests/ballot.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot.test.ts @@ -134,6 +134,27 @@ module.exports = { .sendKeys('*[data-id$="scConfigFilePathInput"]', browser.Keys.ENTER) .openFile('Untitled.sol') .verifyContracts(['Ballot'], {wait: 2000, runs: '300'}) + }, + + 'Compile and deploy sample yul file': function (browser: NightwatchBrowser) { + browser + .addFile('sample.yul', {content: yulSample}) + .clickLaunchIcon('solidity') + .waitForElementVisible('*[data-id="scConfigExpander"]') + .click('*[data-id="scManualConfiguration"]') + .waitForElementVisible('select[id="compilierLanguageSelector"]', 10000) + .click('select[id="compilierLanguageSelector"]') + .click('select[id="compilierLanguageSelector"] option[value=Yul]') + .waitForElementContainsText('[data-id="compiledContracts"]', 'Contract', 60000) + .clickLaunchIcon('udapp') + .click('*[data-id="Deploy - transact (not payable)"]') + .waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]', 60000) + .testFunction('last', + { + status: 'true Transaction mined and execution succeed', + to: 'Contract.(constructor)' + }) + .pause(3000) .end() } } @@ -387,4 +408,19 @@ const configFile = ` "evmVersion": "byzantium" } } +` + +const yulSample = ` +object "Contract" { + code { + function power(base, exponent) -> result + { + result := 1 + for { let i := 0 } lt(i, exponent) { i := add(i, 1) } + { + result := mul(result, base) + } + } + } +} ` \ No newline at end of file diff --git a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx index 80d5e88e9f..34613067a2 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx @@ -765,7 +765,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
- +
From beef736b7296dc6c9ce8668580bd7e7f005838e1 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Wed, 27 Jul 2022 12:30:36 +0530 Subject: [PATCH 07/69] e2e fix --- apps/remix-ide-e2e/src/tests/ballot.test.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/ballot.test.ts b/apps/remix-ide-e2e/src/tests/ballot.test.ts index 04fd37077f..fc090988e1 100644 --- a/apps/remix-ide-e2e/src/tests/ballot.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot.test.ts @@ -149,12 +149,8 @@ module.exports = { .clickLaunchIcon('udapp') .click('*[data-id="Deploy - transact (not payable)"]') .waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]', 60000) - .testFunction('last', - { - status: 'true Transaction mined and execution succeed', - to: 'Contract.(constructor)' - }) - .pause(3000) + .journalLastChildIncludes('Contract.(constructor)') + .journalLastChildIncludes('data: 0x602...0565b') .end() } } From ee3c9ade965d4a111c22d2c21d5338b26ddab0d6 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Wed, 27 Jul 2022 13:43:11 +0530 Subject: [PATCH 08/69] bump remixd --- libs/remixd/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remixd/package.json b/libs/remixd/package.json index 9cee73f6e9..f46b7c0d97 100644 --- a/libs/remixd/package.json +++ b/libs/remixd/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remixd", - "version": "0.6.4", + "version": "0.6.5", "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", From 95a78dce0d3beaf12d988e88af3f758a43fec15d Mon Sep 17 00:00:00 2001 From: David Disu Date: Mon, 25 Jul 2022 15:09:58 +0100 Subject: [PATCH 09/69] Enable deploy with proxy url params --- .../src/lib/constants/uups.ts | 3 +- .../src/lib/openzeppelin-proxy.ts | 52 +++++++++++-------- .../src/lib/components/contractGUI.tsx | 22 +++++--- 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/libs/remix-core-plugin/src/lib/constants/uups.ts b/libs/remix-core-plugin/src/lib/constants/uups.ts index 606d62dd77..66d28acc59 100644 --- a/libs/remix-core-plugin/src/lib/constants/uups.ts +++ b/libs/remix-core-plugin/src/lib/constants/uups.ts @@ -102,4 +102,5 @@ export const UUPSupgradeAbi = { "outputs": [], "stateMutability": "nonpayable", "type": "function" -} \ No newline at end of file +} +export const EnableProxyURLParam = 'deployProxy' \ No newline at end of file diff --git a/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts b/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts index ef03092cb8..25aa04c91e 100644 --- a/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts +++ b/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts @@ -1,6 +1,6 @@ import { Plugin } from '@remixproject/engine' import { ContractAST, ContractSources, DeployOptions } from '../types/contract' -import { UUPS, UUPSABI, UUPSBytecode, UUPSfunAbi, UUPSupgradeAbi } from './constants/uups' +import { EnableProxyURLParam, UUPS, UUPSABI, UUPSBytecode, UUPSfunAbi, UUPSupgradeAbi } from './constants/uups' const proxyProfile = { name: 'openzeppelin-proxy', @@ -33,31 +33,39 @@ export class OpenZeppelinProxy extends Plugin { async getProxyOptions (data: ContractSources, file: string): Promise<{ [name: string]: DeployOptions }> { const contracts = data.contracts[file] const ast = data.sources[file].ast - const inputs = {} if (this.kind === 'UUPS') { - Object.keys(contracts).map(name => { - if (ast) { - const UUPSSymbol = ast.exportedSymbols[UUPS] ? ast.exportedSymbols[UUPS][0] : null - - ast.absolutePath === file && ast.nodes.map((node) => { - if (node.name === name && node.linearizedBaseContracts.includes(UUPSSymbol)) { - const abi = contracts[name].abi - const initializeInput = abi.find(node => node.name === 'initialize') - - inputs[name] = { - options: [{ title: 'Deploy with Proxy', active: false }, { title: 'Upgrade with Proxy', active: false }], - initializeOptions: { - inputs: initializeInput, - initializeInputs: initializeInput ? this.blockchain.getInputs(initializeInput) : null - } + const options = await (this.getUUPSContractOptions(contracts, ast, file)) + + return options + } + } + + async getUUPSContractOptions (contracts, ast, file) { + const options = {} + + await Promise.all(Object.keys(contracts).map(async (name) => { + if (ast) { + const UUPSSymbol = ast.exportedSymbols[UUPS] ? ast.exportedSymbols[UUPS][0] : null + + await Promise.all(ast.absolutePath === file && ast.nodes.map(async (node) => { + if (node.name === name && node.linearizedBaseContracts.includes(UUPSSymbol)) { + const abi = contracts[name].abi + const initializeInput = abi.find(node => node.name === 'initialize') + const isDeployWithProxyEnabled: boolean = await this.call('config', 'getAppParameter', EnableProxyURLParam) || false + + options[name] = { + options: [{ title: 'Deploy with Proxy', active: isDeployWithProxyEnabled }, { title: 'Upgrade with Proxy', active: false }], + initializeOptions: { + inputs: initializeInput, + initializeInputs: initializeInput ? this.blockchain.getInputs(initializeInput) : null } } - }) - } - }) - } - return inputs + } + })) + } + })) + return options } async executeUUPSProxy(implAddress: string, args: string | string [] = '', initializeABI, implementationContractObject): Promise { diff --git a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx index 7fe409e511..9cc5b061b2 100644 --- a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx @@ -24,6 +24,16 @@ export function ContractGUI (props: ContractGUIProps) { const initializeFields = useRef>([]) const basicInputRef = useRef() + useEffect(() => { + if (props.deployOption && Array.isArray(props.deployOption)) { + if (props.deployOption[0] && props.deployOption[0].title === 'Deploy with Proxy') { + handleDeployProxySelect(props.deployOption[0].active) + } else if (props.deployOption[1] && props.deployOption[1].title === 'Deploy with Proxy') { + handleUpgradeImpSelect(props.deployOption[1].active) + } + } + }, [props.deployOption]) + useEffect(() => { if (props.title) { setTitle(props.title) @@ -179,9 +189,7 @@ export function ContractGUI (props: ContractGUIProps) { setToggleDeployProxy(!toggleDeployProxy) } - const handleDeployProxySelect = (e) => { - const value = e.target.checked - + const handleDeployProxySelect = (value: boolean) => { if (value) setToggleUpgradeImp(false) setToggleDeployProxy(value) setDeployState({ upgrade: false, deploy: value }) @@ -191,9 +199,7 @@ export function ContractGUI (props: ContractGUIProps) { setToggleUpgradeImp(!toggleUpgradeImp) } - const handleUpgradeImpSelect = (e) => { - const value = e.target.checked - + const handleUpgradeImpSelect = (value: boolean) => { setToggleUpgradeImp(value) if (value) { setToggleDeployProxy(false) @@ -264,7 +270,7 @@ export function ContractGUI (props: ContractGUIProps) { data-id="contractGUIDeployWithProxy" className="form-check-input custom-control-input" type="checkbox" - onChange={handleDeployProxySelect} + onChange={(e) => handleDeployProxySelect(e.target.checked)} checked={deployState.deploy} />