Merge branch 'master' of https://github.com/ethereum/remix-project into editorcontext

pull/5370/head
filip mertens 3 years ago
commit 148b5749ac
  1. 44
      .circleci/config.yml
  2. 6
      .github/workflows/publish-action.yml
  3. 49
      README.md
  4. 4
      apps/remix-ide-e2e/src/select_tests.sh
  5. 2
      apps/remix-ide-e2e/src/tests/compiler_api.test.ts
  6. 2
      apps/remix-ide-e2e/src/tests/fileManager_api.test.ts
  7. 22
      apps/remix-ide-e2e/src/tests/plugin_api.ts
  8. 2
      apps/remix-ide-e2e/src/tests/recorder.test.ts
  9. 2
      apps/remix-ide-e2e/src/tests/url.test.ts
  10. 112
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  11. 4
      apps/remix-ide/.travis.yml
  12. 44
      apps/remix-ide/README.md
  13. 8
      apps/remix-ide/ci/browser_test.sh
  14. 6
      apps/remix-ide/ci/browser_tests.sh
  15. 6
      apps/remix-ide/ci/browser_tests_plugin_api.sh
  16. 8
      apps/remix-ide/ci/flaky.sh
  17. 2
      apps/remix-ide/ci/lint.sh
  18. 4
      apps/remix-ide/docs/locations.md
  19. 5
      apps/remix-ide/docs/remixd.md
  20. 6
      apps/remix-ide/release-process.md
  21. BIN
      apps/remix-ide/remix-screenshot-400h.png
  22. BIN
      apps/remix-ide/remix_screenshot.png
  23. 20
      apps/remix-ide/src/app/panels/tab-proxy.js
  24. 2
      apps/remix-ide/src/app/plugins/config.ts
  25. 2
      apps/remix-ide/src/app/tabs/ganache-provider.tsx
  26. 5
      apps/remix-ide/src/remixAppManager.js
  27. 6
      apps/solidity-compiler/src/app/compiler-api.ts
  28. 27
      apps/solidity-compiler/src/app/compiler.ts
  29. 2
      libs/remix-analyzer/README.md
  30. 2
      libs/remix-astwalker/README.md
  31. 2
      libs/remix-debug/README.md
  32. 2
      libs/remix-lib/README.md
  33. 2
      libs/remix-lib/src/types/ICompilerApi.ts
  34. 2
      libs/remix-simulator/README.md
  35. 2
      libs/remix-solidity/README.md
  36. 6
      libs/remix-solidity/src/compiler/compiler-input.ts
  37. 42
      libs/remix-solidity/src/compiler/compiler.ts
  38. 2
      libs/remix-solidity/src/compiler/types.ts
  39. 4
      libs/remix-tests/README.md
  40. 2
      libs/remix-tests/tests/testRunner.cli.spec.ts
  41. 22
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  42. 1
      libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx
  43. 6
      libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
  44. 51
      libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx
  45. 7
      libs/remix-ui/run-tab/src/lib/css/card.css
  46. 15
      libs/remix-ui/run-tab/src/lib/css/run-tab.css
  47. 3
      libs/remix-ui/run-tab/src/lib/types/index.ts
  48. 218
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  49. 18
      libs/remix-ui/solidity-compiler/src/lib/compilerConfiguration.tsx
  50. 9
      libs/remix-ui/solidity-compiler/src/lib/css/style.css
  51. 16
      libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts
  52. 18
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  53. 2
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  54. 2
      libs/remix-ui/solidity-compiler/tsconfig.json
  55. 2
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
  56. 2
      libs/remix-ui/tree-view/src/lib/remix-ui-tree-view.tsx
  57. 2
      libs/remix-ui/workspace/src/lib/components/file-label.tsx
  58. 5
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  59. 2
      libs/remix-url-resolver/README.md
  60. 2
      libs/remix-ws-templates/README.md
  61. 4
      libs/remix-ws-templates/src/index.ts
  62. 8
      libs/remix-ws-templates/src/templates/ozerc20/index.ts
  63. 2
      libs/remix-ws-templates/src/templates/ozerc20/scripts/ethers-lib.ts
  64. 2
      libs/remix-ws-templates/src/templates/ozerc20/scripts/web3-lib.ts
  65. 14
      libs/remix-ws-templates/src/templates/ozerc721/contracts/SampleERC721.sol
  66. 16
      libs/remix-ws-templates/src/templates/ozerc721/index.ts
  67. 10
      libs/remix-ws-templates/src/templates/ozerc721/scripts/deploy_with_ethers.ts
  68. 10
      libs/remix-ws-templates/src/templates/ozerc721/scripts/deploy_with_web3.ts
  69. 26
      libs/remix-ws-templates/src/templates/ozerc721/scripts/ethers-lib.ts
  70. 27
      libs/remix-ws-templates/src/templates/ozerc721/scripts/web3-lib.ts
  71. 18
      libs/remix-ws-templates/src/templates/ozerc721/tests/SampleERC721_test.sol
  72. 10
      libs/remix-ws-templates/src/templates/remixDefault/index.ts
  73. 31
      libs/remix-ws-templates/src/templates/zeroxErc20/contracts/SampleERC20.sol
  74. 16
      libs/remix-ws-templates/src/templates/zeroxErc20/index.ts
  75. 10
      libs/remix-ws-templates/src/templates/zeroxErc20/scripts/deploy_with_ethers.ts
  76. 10
      libs/remix-ws-templates/src/templates/zeroxErc20/scripts/deploy_with_web3.ts
  77. 26
      libs/remix-ws-templates/src/templates/zeroxErc20/scripts/ethers-lib.ts
  78. 27
      libs/remix-ws-templates/src/templates/zeroxErc20/scripts/web3-lib.ts
  79. 18
      libs/remix-ws-templates/src/templates/zeroxErc20/tests/SampleERC20_test.sol
  80. 4
      libs/remixd/README.md
  81. 2
      libs/remixd/nodemon.json
  82. 2
      libs/remixd/src/bin/remixd.ts
  83. 48108
      package-lock.json
  84. 82
      package.json
  85. 36
      release-management.md
  86. 2
      release-process.md
  87. 24426
      yarn.lock

@ -30,16 +30,16 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "package-lock.json" }}
- run: npm install
- run: yarn install
- save_cache:
key: v1-deps-{{ checksum "package-lock.json" }}
paths:
- node_modules
- run: npm run downloadsolc_assets
- run: yarn run downloadsolc_assets
- run: npx nx build remix-ide
- run: npx nx build remix-ide-e2e-src-local-plugin
- run: npm run build:libs
- run: yarn run build:libs
- run: mkdir persist && zip -r persist/dist.zip dist
- persist_to_workspace:
root: .
@ -65,7 +65,7 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "package-lock.json" }}
- run: npm install
- run: yarn install
- run:
name: Remix Libs Linting
command: ./apps/remix-ide/ci/lint.sh
@ -92,9 +92,9 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "package-lock.json" }}
- run: npm i
- run: cd dist/libs/remix-tests && npm install
- run: npm run test:libs
- run: yarn install
- run: cd dist/libs/remix-tests && yarn install
- run: yarn run test:libs
remix-ide-chrome:
docker:
@ -128,7 +128,7 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "package-lock.json" }}
- run: npm install
- run: yarn install
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
@ -171,7 +171,7 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "package-lock.json" }}
- run: npm install
- run: yarn install
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
@ -214,7 +214,7 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "package-lock.json" }}
- run: npm install
- run: yarn install
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
@ -256,7 +256,7 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "package-lock.json" }}
- run: npm install
- run: yarn install
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
@ -299,7 +299,7 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "package-lock.json" }}
- run: npm install
- run: yarn install
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
@ -328,9 +328,9 @@ jobs:
steps:
- checkout
- run: npm install
- run: npm run downloadsolc_assets
- run: npm run build:production
- run: yarn install
- run: yarn run downloadsolc_assets
- run: yarn run build:production
- run:
name: Deploy
command: |
@ -357,9 +357,9 @@ jobs:
steps:
- checkout
- run: npm install
- run: npm run downloadsolc_assets
- run: npm run build:production
- run: yarn install
- run: yarn run downloadsolc_assets
- run: yarn run build:production
- run:
name: Deploy
command: |
@ -385,10 +385,10 @@ jobs:
steps:
- checkout
- run: npm install
- run: npm run build:libs
- run: npm run downloadsolc_assets
- run: npm run build:production
- run: yarn install
- run: yarn run build:libs
- run: yarn run downloadsolc_assets
- run: yarn run build:production
- run:
name: Deploy
command: |

@ -9,11 +9,11 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- run: npm install
- run: yarn install
- run: ls
- run: pwd
- run: npm run downloadsolc_assets
- run: npm run build:production
- run: yarn run downloadsolc_assets
- run: yarn run build:production
- run: echo "action_state=$('./apps/remix-ide/ci/publishIpfs')" >> $GITHUB_ENV
- uses: mshick/add-pr-comment@v1
with:

@ -8,18 +8,23 @@
[![Twitter Follow](https://img.shields.io/twitter/follow/ethereumremix?style=social)](https://twitter.com/ethereumremix)
# Remix Project
**Remix Project** is a rich toolset including Remix IDE, a comprehensive smart contract development tool. The Remix Project also includes Remix Plugin Engine and Remix Libraries which are low-level tools for wider use.
**Remix Project** is a platform for development tools that use a plugin architecture. It encompasses sub-projects including Remix Plugin Engine, Remix Libraries, and of course Remix IDE.
## Remix IDE
**Remix IDE** is used for the entire journey of contract development by users of any knowledge level. It fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. The IDE comes in 2 flavors and a VSCode extension:
**Remix IDE** is an open source web and desktop application. It fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. Remix is used for the **entire journey of contract development with [Solidity language](https://soliditylang.org/)** as well as a playground for learning and teaching [Ethereum](https://ethereum.org/).
**Remix Online IDE**, see: [https://remix.ethereum.org](https://remix.ethereum.org)
Start developing using Remix on browser, visit: [https://remix.ethereum.org](https://remix.ethereum.org)
:point_right: Supported browsers: Firefox v100.0.1 & Chrome v101.0.4951.64. No support for Remix's use on tablets or smartphones or telephones.
For desktop version, see releases: [https://github.com/ethereum/remix-desktop/releases](https://github.com/ethereum/remix-desktop/releases)
**Remix Desktop IDE**, see releases: [https://github.com/ethereum/remix-desktop/releases](https://github.com/ethereum/remix-desktop/releases)
![Remix screenshot](https://github.com/ethereum/remix-project/raw/master/apps/remix-ide/remix_screenshot.png)
![Remix screenshot](https://github.com/ethereum/remix-project/raw/master/apps/remix-ide/remix-screenshot-400h.png)
:point_right: **Remix libraries** work as a core of native plugins of Remix IDE. Read more about libraries [here](libs/README.md)
**VSCode extension**, see: [Ethereum-Remix](https://marketplace.visualstudio.com/items?itemName=RemixProject.ethereum-remix)
## Remix libraries
Remix libraries are essential for Remix IDE's native plugins. Read more about libraries [here](libs/README.md)
## Offline Usage
@ -30,7 +35,7 @@ Note: It contains the latest supported version of Solidity available at the time
## Setup
* Install **NPM** and **Node.js**. See [Guide](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) <br/>
* Install **Yarn** and **Node.js**. See [Guide for NodeJs](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) and [Yarn install](https://classic.yarnpkg.com/lang/en/docs/install)<br/>
*Supported versions:*
```bash
"engines": {
@ -40,7 +45,7 @@ Note: It contains the latest supported version of Solidity available at the time
```
* Install [Nx CLI](https://nx.dev/react/cli/overview) globally to enable running **nx executable commands**.
```bash
npm install -g @nrwl/cli
yarn global add @nrwl/cli
```
* Clone the github repository (`wget` need to be installed first):
@ -50,8 +55,8 @@ git clone https://github.com/ethereum/remix-project.git
* Build `remix-project`:
```bash
cd remix-project
npm install
npm run build:libs // Build remix libs
yarn install
yarn run build:libs // Build remix libs
nx build
nx serve
```
@ -63,12 +68,12 @@ Go to your `text editor` and start developing. Browser will automatically refres
## Production Build
To generate react production builds for remix-project.
```bash
npm run build:production
yarn run build:production
```
Build can be found in `remix-project/dist/apps/remix-ide` directory.
```bash
npm run serve:production
yarn run serve:production
```
Production build will be served by default to `http://localhost:8080/` or `http://127.0.0.1:8080/`
@ -133,17 +138,17 @@ For example, to run unit tests of `remix-analyzer`, use `nx test remix-analyzer`
To run the Selenium tests via Nightwatch:
- Install Selenium for first time: `npm run selenium-install`
- Run a selenium server: `npm run selenium`
- Install Selenium for first time: `yarn run selenium-install`
- Run a selenium server: `yarn run selenium`
- Build & Serve Remix: `nx serve`
- Run all the end-to-end tests:
for Firefox: `npm run nightwatch_local_firefox`, or
for Firefox: `yarn run nightwatch_local_firefox`, or
for Google Chrome: `npm run nightwatch_local_chrome`
for Google Chrome: `yarn run nightwatch_local_chrome`
- Run a specific test case instead, use a command like this:
- npm run nightwatch_local_ballot
- yarn run nightwatch_local_ballot
The package.json file contains a list of all the tests you can run.
@ -163,7 +168,7 @@ To run the Selenium tests via Nightwatch:
There is a script to allow selecting the browser and a specific test to run:
```
npm run select_test
yarn run select_test
```
You need to have
@ -209,13 +214,13 @@ module.exports = {
- change package json to locally run all group tests:
```
"nightwatch_local_debugger": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.spec.js --env=chrome",
"nightwatch_local_debugger": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.spec.js --env=chrome",
```
- run the build script to build the test files if you want to run the locally
```
npm run build:e2e
yarn run build:e2e
```
### Locally testing group tests
@ -229,12 +234,12 @@ You can tag any test with a groupname, for example, #group10 and easily run the
This script will give you an option menu, just select the test you want
```
npm run select_test
yarn run select_test
```
#### method 2
```
npm run group_test --test=debugger --group=10 --env=chromeDesktop
yarn run group_test --test=debugger --group=10 --env=chromeDesktop
```
- specify chromeDesktop to see the browser action, use 'chrome' to run it headless

@ -24,7 +24,7 @@ do
*) echo "invalid option $REPLY";;
esac
done
npm run build:e2e
yarn run build:e2e
PS3='Select a test or command: '
TESTFILES=( $(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test\|plugin_api" | sort ) )
@ -42,6 +42,6 @@ do
done
else
# run the selected test
npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $opt --env=$BROWSER
yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $opt --env=$BROWSER
fi
done

@ -46,7 +46,7 @@ module.exports = {
browser
.addFile('test_updateConfiguration.js', { content: updateConfiguration })
.executeScript('remix.exeCurrent()')
.pause(5000)
.pause(15000)
.addFile('test_updateConfiguration.sol', { content: simpleContract })
.verifyContracts(['StorageTestUpdateConfiguration'], { wait: 5000, version: '0.6.8+commit.0bbfe453' })
},

@ -71,7 +71,7 @@ module.exports = {
.addFile('mkdirFile.js', { content: executeMkdir })
.executeScript('remix.exeCurrent()')
.pause(2000)
.waitForElementPresent('[data-id="treeViewLitreeViewItemTest_Folder"]', 60000)
.waitForElementPresent('[data-id="treeViewLitreeViewItemTest_Folder"]', 80000)
},
'Should execute `readdir` api from file manager external api #group3': function (browser: NightwatchBrowser) {

@ -230,7 +230,13 @@ module.exports = {
},
'Should get current files #group7': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'fileManager:readdir', { contracts: { isDirectory: true }, scripts: { isDirectory: true }, tests: { isDirectory: true }, 'README.txt': { isDirectory: false } }, null, '/')
await clickAndCheckLog(browser, 'fileManager:readdir', {
'compiler_config.json': { isDirectory: false },
contracts: { isDirectory: true },
scripts: { isDirectory: true },
tests: { isDirectory: true },
'README.txt': { isDirectory: false }
}, null, '/')
},
'Should throw error on current file #group7': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'fileManager:getCurrentFile', 'Error from IDE : Error: No such file or directory No file selected', null, null)
@ -280,12 +286,20 @@ module.exports = {
'Should create empty workspace #group2': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, ['emptyworkspace', true])
await clickAndCheckLog(browser, 'filePanel:getCurrentWorkspace', { name: 'emptyworkspace', isLocalhost: false, absolutePath: '.workspaces/emptyworkspace' }, null, null)
await clickAndCheckLog(browser, 'fileManager:readdir', {}, null, '/')
await clickAndCheckLog(browser, 'fileManager:readdir', {
'compiler_config.json': { isDirectory: false }
}, null, '/')
},
'Should create workspace #group2': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, 'testspace')
await clickAndCheckLog(browser, 'filePanel:getCurrentWorkspace', { name: 'testspace', isLocalhost: false, absolutePath: '.workspaces/testspace' }, null, null)
await clickAndCheckLog(browser, 'fileManager:readdir', { contracts: { isDirectory: true }, scripts: { isDirectory: true }, tests: { isDirectory: true }, 'README.txt': { isDirectory: false } }, null, null)
await clickAndCheckLog(browser, 'fileManager:readdir', {
'compiler_config.json': { isDirectory: false },
contracts: { isDirectory: true },
scripts: { isDirectory: true },
tests: { isDirectory: true },
'README.txt': { isDirectory: false }
}, null, null)
},
'Should get all workspaces #group2': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'filePanel:getWorkspaces', ['default_workspace', 'emptyworkspace', 'testspace'], null, null)
@ -409,7 +423,7 @@ module.exports = {
.addFile('test_modal.js', { content: testModalToasterApi })
.executeScript('remix.execute(\'test_modal.js\')')
.useCss()
.waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]')
.waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]', 60000)
.assert.containsText('*[data-id="test_id_1_ModalDialogModalBody-react"]', 'message 1')
.modalFooterOKClick('test_id_1_')
// check the script runner notifications

@ -17,7 +17,7 @@ module.exports = {
.pause(5000)
.clickLaunchIcon('udapp')
.selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') // this account will be used for this test suite
.click('[data-id="udapp_arrow"]')
.click('[data-id="udappRecorderTitleExpander"]')
.click('[data-id="runtransaction"]')
.clickInstance(0)
.clickInstance(1)

@ -81,6 +81,7 @@ module.exports = {
.refresh()
.pause(5000)
.clickLaunchIcon('solidity')
.click('*[data-id="scConfigExpander"]')
.assert.containsText('#versionSelector option[data-id="selected"]', '0.7.4+commit.3f05b770')
.assert.containsText('#evmVersionSelector option[data-id="selected"]', 'istanbul')
.assert.containsText('#compilierLanguageSelector option[data-id="selected"]', 'Yul')
@ -96,6 +97,7 @@ module.exports = {
.pause(5000)
.clickLaunchIcon('solidity')
.pause(5000)
.click('*[data-id="scConfigExpander"]')
.assert.containsText('#versionSelector option[data-id="selected"]', 'custom')
// default values
.assert.containsText('#evmVersionSelector option[data-id="selected"]', 'default')

@ -50,11 +50,42 @@ module.exports = {
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/3_Ballot.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
// check js and ts files are not transformed
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.pause(2000)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => { `) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/storage.test.js"]')
.click('*[data-id="treeViewLitreeViewItemtests/storage.test.js"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`const { expect } = require("chai");`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/Ballot_test.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemREADME.txt"]')
},
@ -70,14 +101,14 @@ module.exports = {
.click('select[id="wstemplate"] option[value=blank]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(1000)
.pause(100)
.assert.elementPresent('*[data-id="treeViewUltreeViewMenu"]')
.execute(function () {
const fileList = document.querySelector('*[data-id="treeViewUltreeViewMenu"]')
return fileList.getElementsByTagName('li').length;
}, [], function(result){
// check there are no files in FE
browser.assert.equal(result.value, 0, 'Incorrect number of files');
// check there are no files in FE except config file
browser.assert.equal(result.value, 1, 'Incorrect number of files');
});
},
@ -92,18 +123,91 @@ module.exports = {
.click('select[id="wstemplate"] option[value=ozerc20]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(1000)
.pause(100)
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/SampleERC20.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
// check js and ts files are not transformed
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => { `) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/SampleERC20_test.sol"]')
},
'Should create ERC721 workspace with files': function (browser: NightwatchBrowser) {
browser
.click('*[data-id="workspaceCreate"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > span')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc721' })
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=ozerc721]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/SampleERC721.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
// check js and ts files are not transformed
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => { `) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/SampleERC721_test.sol"]')
},
// WORKSPACE TEMPLATES E2E END
'Should create two workspace and switch to the first one': function (browser: NightwatchBrowser) {

@ -9,8 +9,8 @@ branches:
- master
- remix_live
script:
- npm install
- npm run lint && npm run test && npm run make-mock-compiler && npm run build
- yarn install
- yarn run lint && yarn run test && yarn run make-mock-compiler && yarn run build
- wget http://selenium-release.storage.googleapis.com/3.5/selenium-server-standalone-3.5.3.jar
- wget http://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip
- unzip chromedriver_linux64.zip

@ -26,7 +26,7 @@ Install **npm** and **node.js** (see https://docs.npmjs.com/getting-started/inst
Remix-ide has been published as an npm module:
```bash
npm install remix-ide -g
yarn global add remix-ide
remix-ide
```
Or if you want to clone the github repository (`wget` need to be installed first) :
@ -36,12 +36,12 @@ git clone https://github.com/ethereum/remix-ide.git
git clone https://github.com/ethereum/remix.git # only if you plan to link remix and remix-ide repositories and develop on it.
cd remix # only if you plan to link remix and remix-ide repositories and develop on it.
npm install # only if you plan to link remix and remix-ide repositories and develop on it.
npm run bootstrap # only if you plan to link remix and remix-ide repositories and develop on it.
yarn install # only if you plan to link remix and remix-ide repositories and develop on it.
yarn run bootstrap # only if you plan to link remix and remix-ide repositories and develop on it.
cd remix-ide
npm install
npm run setupremix # only if you plan to link remix and remix-ide repositories and develop on it.
yarn install
yarn run setupremix # only if you plan to link remix and remix-ide repositories and develop on it.
npm start
```
@ -112,40 +112,40 @@ nvm --version
Register new unit test files in `test/index.js`.
The tests are written using [tape](https://www.npmjs.com/package/tape).
Run the unit tests via: `npm test`
Run the unit tests via: `yarn test`
For local headless browser tests run `npm run test-browser`
(requires Selenium to be installed - can be done with `npm run selenium-install`)
For local headless browser tests run `yarn run test-browser`
(requires Selenium to be installed - can be done with `yarn run selenium-install`)
Running unit tests via `npm test` requires at least node v7.0.0
Running unit tests via `yarn test` requires at least node v7.0.0
## Browser Testing
To run the Selenium tests via Nightwatch:
- Build Remix IDE and serve it: `npm run build && npm run serve` # starts web server at localhost:8080
- Make sure Selenium is installed `npm run selenium-install` # don't need to repeat
- Run a selenium server `npm run selenium`
- Run all the tests `npm run nightwatch_local_firefox` or `npm run nightwatch_local_chrome`
- Build Remix IDE and serve it: `yarn run build && yarn run serve` # starts web server at localhost:8080
- Make sure Selenium is installed `yarn run selenium-install` # don't need to repeat
- Run a selenium server `yarn run selenium`
- Run all the tests `yarn run nightwatch_local_firefox` or `yarn run nightwatch_local_chrome`
- Or run a specific test case:
- npm run nightwatch_local_ballot
- yarn run nightwatch_local_ballot
- npm run nightwatch_local_libraryDeployment
- yarn run nightwatch_local_libraryDeployment
- npm run nightwatch_local_solidityImport
- yarn run nightwatch_local_solidityImport
- npm run nightwatch_local_recorder
- yarn run nightwatch_local_recorder
- npm run nightwatch_local_transactionExecution
- yarn run nightwatch_local_transactionExecution
- npm run nightwatch_local_staticAnalysis
- yarn run nightwatch_local_staticAnalysis
- npm run nightwatch_local_signingMessage
- yarn run nightwatch_local_signingMessage
- npm run nightwatch_local_console
- yarn run nightwatch_local_console
- npm run nightwatch_local_remixd # remixd needs to be run
- yarn run nightwatch_local_remixd # remixd needs to be run
**NOTE:**
- **the `ballot` tests suite** requires to run `ganache-cli` locally.

@ -6,14 +6,14 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID"
TEST_EXITCODE=0
npm run ganache-cli &
npm run serve:production &
yarn run ganache-cli &
yarn run serve:production &
echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' &
npm run remixd &
yarn run remixd &
sleep 5
npm run build:e2e
yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | sort | circleci tests split )
for TESTFILE in $TESTFILES; do

@ -15,13 +15,13 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID"
TEST_EXITCODE=0
npm run ganache-cli &
npm run serve &
yarn run ganache-cli &
yarn run serve &
setupRemixd
sleep 5
npm run nightwatch_parallel || TEST_EXITCODE=1
yarn run nightwatch_parallel || TEST_EXITCODE=1
TESTFILES=$(circleci tests glob "./apps/remix-ide/test-browser/tests/**/*.test.js" | circleci tests split )
for TESTFILE in $TESTFILES; do
./node_modules/.bin/nightwatch --config ./apps/remix-ide/nightwatch.js --env chrome $TESTFILE || TEST_EXITCODE=1

@ -6,13 +6,13 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID"
TEST_EXITCODE=0
npm run ganache-cli &
npm run serve:production &
yarn run ganache-cli &
yarn run serve:production &
npx nx serve remix-ide-e2e-src-local-plugin &
sleep 5
npm run build:e2e
yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "plugin_api" | sort | circleci tests split )
for TESTFILE in $TESTFILES; do

@ -2,7 +2,7 @@
set -e
npm run build:e2e
yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.flaky" | sort )
# count test files
@ -18,10 +18,10 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID"
TEST_EXITCODE=0
npm run ganache-cli &
npm run serve:production &
yarn run ganache-cli &
yarn run serve:production &
echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' &
npm run remixd &
yarn run remixd &
npx nx serve remix-ide-e2e-src-local-plugin &
sleep 5

@ -13,7 +13,7 @@ KEYS=$(jq -r '.projects | keys' workspace.json | tr -d '[],"')
then
echo ${row}
fi
done) | circleci tests split | { while read i;do npm run lint $i; done }
done) | circleci tests split | { while read i;do yarn run lint $i; done }
echo "$TEST_EXITCODE"
if [ "$TEST_EXITCODE" -eq 1 ]

@ -5,6 +5,6 @@ So if you've found the documentation to Remix but don't know where to find Remix
- An online version is available at [https://remix.ethereum.org](https://remix.ethereum.org). This version is stable and is updated at almost every release.
- An alpha online version is available at [https://remix-alpha.ethereum.org](https://remix-alpha.ethereum.org). This is not a stable version.
- npm `remix-ide` package `npm install remix-ide -g`. `remix-ide` create a new instance of `Remix IDE` available at [http://127.0.0.1:8080](http://127.0.0.1:8080) and make the current folder available to Remix IDE by automatically starting `remixd`.
- npm `remix-ide` package `yarn global add remix-ide`. `remix-ide` create a new instance of `Remix IDE` available at [http://127.0.0.1:8080](http://127.0.0.1:8080) and make the current folder available to Remix IDE by automatically starting `remixd`.
see [Connection to `remixd`](https://remix-ide.readthedocs.io/en/latest/remixd.html) for more information about sharing local file with `Remix IDE`.
- Github release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `npm run build`.
- Github release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `yarn run build`.

@ -8,10 +8,7 @@ The code of `remixd` is
[here](https://github.com/ethereum/remixd) .
`remixd` can be globally installed using the following command:
`npm install -g remixd`
Or just install it in the directory of your choice by removing the -g flag:
`npm install remixd`
`yarn global add @remix-project/remixd`
Then from the terminal, the command `remixd -s <absolute-path-to-the-shared-folder> --remix-ide <your-remix-ide-URL-instance>` will start `remixd` and will share the given folder with remix-ide.

@ -9,7 +9,6 @@ This document includes:
- git checkout origin/master
- git checkout -b bumpVersion
- update package.json version
- remove package-lock.json version and generate a new one with `npm install`
- merge PR
- git fetch origin master
- git checkout origin/master
@ -18,9 +17,9 @@ This document includes:
- github-changes -o ethereum -r remix-ide -a --only-pulls --use-commit-body --only-merges --between-tags previous_version...next_version
- publish a release in github using the changelog
- rm -rf node_modules
- npm install
- yarn install
- remove all soljson.js files in root folder
- npm run build
- yarn run build
- npm publish
- after remix_live is updated, drop the zip (from https://github.com/ethereum/remix-live/) to the release.
@ -29,7 +28,6 @@ This document includes:
- git checkout origin/master
- git checkout -b bumpVersion
- update package.json version to the new version "vx.x.x-beta.1"
- remove package-lock/json version and generate a new one with `npm install`
- merge PR
- git fetch origin master
- git checkout origin/master

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 KiB

@ -24,7 +24,7 @@ export class TabProxy extends Plugin {
this.themeQuality = 'dark'
}
onActivation () {
async onActivation () {
this.on('theme', 'themeChanged', (theme) => {
this.themeQuality = theme.quality
// update invert for all icons
@ -169,6 +169,13 @@ export class TabProxy extends Plugin {
this.on('manager', 'pluginDeactivated', (profile) => {
this.removeTab(profile.name)
})
try {
this.themeQuality = (await this.call('theme', 'currentTheme') ).quality
} catch (e) {
console.log('theme plugin has an issue: ', e)
}
this.renderComponent()
}
focus (name) {
@ -208,6 +215,7 @@ export class TabProxy extends Plugin {
}
renameTab (oldName, newName) {
// The new tab is being added by FileManager
this.removeTab(oldName)
}
@ -292,7 +300,15 @@ export class TabProxy extends Plugin {
}
updateComponent(state) {
return <TabsUI tabs={state.loadedTabs} onSelect={state.onSelect} onClose={state.onClose} onZoomIn={state.onZoomIn} onZoomOut={state.onZoomOut} onReady={state.onReady} themeQuality={state.themeQuality} />
return <TabsUI
tabs={state.loadedTabs}
onSelect={state.onSelect}
onClose={state.onClose}
onZoomIn={state.onZoomIn}
onZoomOut={state.onZoomOut}
onReady={state.onReady}
themeQuality={state.themeQuality}
/>
}
renderComponent () {

@ -18,7 +18,7 @@ export class ConfigPlugin extends Plugin {
const queryParams = new QueryParams()
const params = queryParams.get()
const config = Registry.getInstance().get('config').api
let param = params[name] || config.get(name) || config.get('settings/' + name)
const param = params[name] || config.get(name) || config.get('settings/' + name)
if (param === 'true') return true
if (param === 'false') return false
return param

@ -23,7 +23,7 @@ export class GanacheProvider extends AbstractProvider {
body (): JSX.Element {
return (
<div> Note: To run Ganache on your system, run
<div className="border p-1">npm install -g ganache</div>
<div className="border p-1">yarn global add ganache</div>
<div className="border p-1">ganache</div>
For more info, visit: <a href="https://github.com/trufflesuite/ganache" target="_blank">Ganache Documentation</a>
<div>Ganache JSON-RPC Endpoint:</div>

@ -7,7 +7,7 @@ const _paq = window._paq = window._paq || []
const requiredModules = [ // services + layout views + system views
'manager', 'config', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme',
'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons',
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic', 'gistHandler', 'layout',
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout',
'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy', 'hardhat-provider', 'compileAndRun', 'search']
const dependentModules = ['git', 'hardhat', 'truffle', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd)
@ -19,7 +19,8 @@ const sensitiveCalls = {
}
export function isNative(name) {
const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification', 'hardhat-provider', 'ganache-provider']
const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'solidity-logic',
'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification', 'hardhat-provider', 'ganache-provider']
return nativePlugins.includes(name) || requiredModules.includes(name)
}

@ -18,7 +18,7 @@ export const CompilerApiMixin = (Base) => class extends Base {
onCurrentFileChanged: (fileName: string) => void
// onResetResults: () => void
onSetWorkspace: (workspace: any) => void
onSetWorkspace: (isLocalhost: boolean, workspaceName: string) => void
onNoFileSelected: () => void
onCompilationFinished: (compilationDetails: { contractMap: { file: string } | Record<string, any>, contractsDetails: Record<string, any> }) => void
onSessionSwitched: () => void
@ -237,12 +237,12 @@ export const CompilerApiMixin = (Base) => class extends Base {
this.on('filePanel', 'setWorkspace', (workspace) => {
this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost)
if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost, workspace.name)
})
this.on('remixd', 'rootFolderChanged', () => {
this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(true)
if (this.onSetWorkspace) this.onSetWorkspace(true, 'localhost')
})
this.on('editor', 'sessionSwitched', () => {

@ -6,31 +6,14 @@ import { CompilerApiMixin } from './compiler-api'
import { ICompilerApi } from '@remix-project/remix-lib-ts'
import { CompileTabLogic } from '@remix-ui/solidity-compiler'
const profile = {
name: 'solidity',
displayName: 'Solidity compiler',
icon: 'assets/img/solidity.webp',
description: 'Compile solidity contracts',
kind: 'compiler',
permission: true,
location: 'sidePanel',
documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html',
version: '0.0.1',
methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile', 'getCompilerState']
}
const defaultAppParameters = {
hideWarnings: false,
autoCompile: false,
includeNightlies: false
}
const defaultCompilerParameters = {
runs: '200',
optimize: false,
version: 'soljson-v0.8.7+commit.e28d00a7',
evmVersion: null, // compiler default
language: 'Solidity'
language: 'Solidity',
useFileConfiguration: false,
configFilePath: "compiler_config.json"
}
export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements ICompilerApi {
constructor () {
@ -48,7 +31,9 @@ export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements
optimize: localStorage.getItem('optimize') === 'true',
version: localStorage.getItem('version') || defaultCompilerParameters.version,
evmVersion: localStorage.getItem('evmVersion') || defaultCompilerParameters.evmVersion, // default
language: localStorage.getItem('language') || defaultCompilerParameters.language
language: localStorage.getItem('language') || defaultCompilerParameters.language,
useFileConfiguration: localStorage.getItem('useFileConfiguration') === 'true',
configFilePath: localStorage.getItem('configFilePath') || defaultCompilerParameters.configFilePath
}
return params
}

@ -10,7 +10,7 @@
### Installation
`@remix-project/remix-analyzer` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-analyzer`
`yarn add @remix-project/remix-analyzer`
### How to use

@ -10,7 +10,7 @@
### Installation
`@remix-project/remix-astwalker` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-astwalker`
`yarn add @remix-project/remix-astwalker`
### How to use

@ -10,7 +10,7 @@
### Installation
`@remix-project/remix-debug` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-debug`
`yarn add @remix-project/remix-debug`
### How to use

@ -10,7 +10,7 @@
### Installation
`@remix-project/remix-lib` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-lib`
`yarn add @remix-project/remix-lib`
### How to use

@ -24,7 +24,7 @@ export interface ICompilerApi {
onCurrentFileChanged: (fileName: string) => void
// onResetResults: () => void,
onSetWorkspace: (workspace: any) => void
onSetWorkspace: (isLocalhost: boolean, workspaceName: string) => void
onNoFileSelected: () => void
onCompilationFinished: (contractsDetails: any, contractMap: any) => void
onSessionSwitched: () => void

@ -10,7 +10,7 @@
### Installation
`@remix-project/remix-simulator` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-simulator`
`yarn add @remix-project/remix-simulator`
### How to use

@ -12,7 +12,7 @@
`@remix-project/remix-solidity` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-solidity`
`yarn add @remix-project/remix-solidity`
### How to use

@ -50,3 +50,9 @@ export function getValidLanguage (val: string): Language {
}
return null
}
export function compilerInputForConfigFile(sources: Source, opts)
{
opts.sources = sources
return JSON.stringify(opts)
}

@ -2,7 +2,7 @@
import { update } from 'solc/abi'
import * as webworkify from 'webworkify-webpack'
import compilerInput from './compiler-input'
import compilerInput, { compilerInputForConfigFile } from './compiler-input'
import EventManager from '../lib/eventManager'
import txHelper from './helper'
import {
@ -31,6 +31,8 @@ export class Compiler {
language: 'Solidity',
compilationStartTime: null,
target: null,
useFileConfiguration: false,
configFileContent: '',
lastCompilationResult: {
data: null,
source: null
@ -111,11 +113,17 @@ export class Compiler {
return { error: 'Deferred import' }
}
let result: CompilationResult = {}
let input
let input = ""
try {
if (source && source.sources) {
const { optimize, runs, evmVersion, language } = this.state
const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state
if (useFileConfiguration) {
input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent))
} else {
input = compilerInput(source.sources, { optimize, runs, evmVersion, language })
}
result = JSON.parse(compiler.compile(input, { import: missingInputsCallback }))
}
} catch (exception) {
@ -184,11 +192,17 @@ export class Compiler {
return { error: 'Deferred import' }
}
let result: CompilationResult = {}
let input: string
let input = ""
try {
if (source && source.sources) {
const { optimize, runs, evmVersion, language } = this.state
const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state
if (useFileConfiguration) {
input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent))
} else {
input = compilerInput(source.sources, { optimize, runs, evmVersion, language })
}
result = JSON.parse(remoteCompiler.compile(input, { import: missingInputsCallback }))
}
} catch (exception) {
@ -290,12 +304,26 @@ export class Compiler {
this.state.compileJSON = (source: SourceWithTarget) => {
if (source && source.sources) {
const { optimize, runs, evmVersion, language } = this.state
const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state
jobs.push({ sources: source })
let input = ""
try {
if (useFileConfiguration) {
input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent))
} else {
input = compilerInput(source.sources, { optimize, runs, evmVersion, language })
}
} catch (exception) {
this.onCompilationFinished({ error: { formattedMessage: exception.message } }, [], source, "", this.state.currentVersion)
return
}
this.state.worker.postMessage({
cmd: 'compile',
job: jobs.length - 1,
input: compilerInput(source.sources, { optimize, runs, evmVersion, language })
input: input
})
}
}

@ -165,6 +165,8 @@ export interface CompilerState {
language: Language,
compilationStartTime: number| null,
target: string | null,
useFileConfiguration: boolean,
configFileContent: string,
lastCompilationResult: {
data: CompilationResult | null,
source: SourceWithTarget | null | undefined

@ -12,11 +12,11 @@ To know more about Remix IDE `Solidity Unit Testing Plugin`, visit [Remix IDE of
### Installation
* As a dev dependency:
`npm install --save-dev @remix-project/remix-tests`
`yarn add --dev @remix-project/remix-tests`
* As a global NPM module to use as CLI:
`npm -g install @remix-project/remix-tests`
`yarn global add @remix-project/remix-tests`
To confirm installation, run:
```

@ -11,7 +11,7 @@ describe('testRunner: remix-tests CLI', () => {
const dirContent = result.stdout.toString()
// Install dependencies if 'node_modules' is not already present
if(!dirContent.includes('node_modules')) {
execSync('npm install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') })
execSync('yarn install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') })
}
}

@ -83,6 +83,25 @@ export interface EditorUIProps {
export const EditorUI = (props: EditorUIProps) => {
const [, setCurrentBreakpoints] = useState({})
const defaultEditorValue = `
\t\t\t\t\t\t\t ____ _____ __ __ ___ __ __ ___ ____ _____
\t\t\t\t\t\t\t| _ \\ | ____| | \\/ | |_ _| \\ \\/ / |_ _| | _ \\ | ____|
\t\t\t\t\t\t\t| |_) | | _| | |\\/| | | | \\ / | | | | | | | _|
\t\t\t\t\t\t\t| _ < | |___ | | | | | | / \\ | | | |_| | | |___
\t\t\t\t\t\t\t|_| \\_\\ |_____| |_| |_| |___| /_/\\_\\ |___| |____/ |_____|\n\n
\t\t\t\t\t\t\tKeyboard Shortcuts:\n
\t\t\t\t\t\t\t\tCTRL + S: Compile the current contract\n
\t\t\t\t\t\t\t\tCtrl + Shift + F : Open the File Explorer\n
\t\t\t\t\t\t\t\tCtrl + Shift + A : Open the Plugin Manager\n
\t\t\t\t\t\t\t\tCTRL + SHIFT + S: Compile the current contract & Run an associated script\n\n
\t\t\t\t\t\t\tImportant Links:\n
\t\t\t\t\t\t\t\tOfficial website about the Remix Project: https://remix-project.org/\n
\t\t\t\t\t\t\t\tOfficial documentation: https://remix-ide.readthedocs.io/en/latest/\n
\t\t\t\t\t\t\t\tGithub: https://github.com/ethereum/remix-project\n
\t\t\t\t\t\t\t\tGitter: https://gitter.im/ethereum/remix\n
\t\t\t\t\t\t\t\tMedium: https://medium.com/remix-ide\n
\t\t\t\t\t\t\t\tTwitter: https://twitter.com/ethereumremix\n
`
const editorRef = useRef(null)
const monacoRef = useRef(null)
const currentFileRef = useRef('')
@ -453,7 +472,8 @@ export const EditorUI = (props: EditorUIProps) => {
language={editorModelsState[props.currentFile] ? editorModelsState[props.currentFile].language : 'text'}
onMount={handleEditorDidMount}
beforeMount={handleEditorWillMount}
options={{ glyphMargin: true }}
options={{ glyphMargin: true, readOnly: true}}
defaultValue={defaultEditorValue}
/>
<div className="contextview">
<RemixUiEditorContextView

@ -4,7 +4,6 @@ import './remix-ui-home-tab.css'
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
import PluginButton from './components/pluginButton' // eslint-disable-line
import { QueryParams } from '@remix-project/remix-lib'
import { ThemeContext, themes } from './themeContext'
declare global {
interface Window {

@ -11,8 +11,8 @@ export function InstanceContainerUI (props: InstanceContainerProps) {
}
return (
<div className="udapp_instanceContainer border-0 list-group-item">
<div className="d-flex justify-content-between align-items-center pl-2 ml-1 mb-2"
<div className="udapp_instanceContainer mt-3 border-0 list-group-item">
<label className="udapp_deployedContracts d-flex justify-content-between align-items-center pl-2 mb-0"
title="Autogenerated generic user interfaces for interaction with deployed contracts">
Deployed Contracts
{ instanceList.length > 0
@ -20,7 +20,7 @@ export function InstanceContainerUI (props: InstanceContainerProps) {
title="Clear instances list and reset recorder" aria-hidden="true">
</i> : null
}
</div>
</label>
{ instanceList.length > 0
? <div> { props.instances.instanceList.map((instance, index) => {
return <UniversalDappUI

@ -1,27 +1,9 @@
// eslint-disable-next-line no-use-before-define
import React from 'react'
import { TreeView, TreeViewItem } from '@remix-ui/tree-view'
import React, {useState} from 'react'
import { RecorderProps } from '../types'
export function RecorderUI (props: RecorderProps) {
const card = (title: string, recorderCount: number) => {
return (
<div className="d-flex justify-content-between align-items-center" onClick={() => {}}>
<div className="pr-1 d-flex flex-row">
<div>{title}</div>
<div>
<div className="d-flex flex-column">
<div className="ml-2 badge badge-pill badge-primary" title="The number of recorded transactions">{recorderCount}</div>
</div>
</div>
</div>
<div>
<div><i className="udapp_arrow fas fa-angle-down" data-id="udapp_arrow"></i></div>
</div>
</div>
)
}
const [toggleExpander, setToggleExpander] = useState<boolean>(false)
const triggerRecordButton = () => {
props.storeScenario(props.scenarioPrompt)
}
@ -30,24 +12,35 @@ export function RecorderUI (props: RecorderProps) {
props.runCurrentScenario(props.gasEstimationPrompt, props.passphrasePrompt, props.mainnetPrompt, props.logBuilder)
}
const toggleClass = () => {
setToggleExpander(!toggleExpander)
}
return (
<div className="udapp_cardContainer list-group-item border-0">
<TreeView>
<TreeViewItem label={card('Transactions recorded', props.count)} showIcon={false} labelClass="ml-n1">
<div className="d-flex flex-column">
<div className="udapp_recorderDescription mt-2">
All transactions (deployed contracts and function executions) in this environment can be saved and replayed in
<div className="udapp_cardContainer list-group-item border border-bottom">
<div className="udapp_recorderSection d-flex justify-content-between" onClick={toggleClass}>
<div className="d-flex">
<label className="mt-1 udapp_recorderSectionLabel">Transactions recorded</label>
<div className="ml-2 mb-2 badge badge-pill badge-primary" title="The number of recorded transactions">{props.count}</div>
</div>
<div>
<span data-id='udappRecorderTitleExpander' onClick={toggleClass}>
<i className={!toggleExpander ? 'fas fa-angle-right' : 'fas fa-angle-down'} aria-hidden="true"></i>
</span>
</div>
</div>
<div className={`border-bottom flex-column ${toggleExpander ? "d-flex" : "d-none"}`}>
<div className="p-2 mt-2">
All transactions (deployed contracts and function executions) can be saved and replayed in
another environment. e.g Transactions created in Javascript VM can be replayed in the Injected Web3.
</div>
<div className="udapp_transactionActions">
<div className="mb-2 udapp_transactionActions">
<i className="fas fa-save savetransaction udapp_recorder udapp_icon"
onClick={triggerRecordButton} title="Save Transactions" aria-hidden="true">
</i>
<i className="fas fa-play runtransaction udapp_runTxs udapp_icon" title="Run Transactions" data-id="runtransaction" aria-hidden="true" onClick={handleClickRunButton}></i>
</div>
</div>
</TreeViewItem>
</TreeView>
</div>
)
}

@ -3,10 +3,3 @@
margin : 0;
background : none;
}
.udapp_arrow {
font-weight : bold;
cursor : pointer;
font-size : 14px;
}
.udapp_arrow:hover {
}

@ -60,6 +60,9 @@
text-align: center;
padding: 0 14px 16px;
}
.udapp_deployedContracts {
font-size: 1rem;
}
.udapp_pendingTxsContainer {
display: flex;
flex-direction: column;
@ -70,9 +73,6 @@
.udapp_container {
padding: 0 24px 16px;
}
.udapp_recorderDescription {
margin: 0 15px 15px 0;
}
.udapp_contractNames {
width: 100%;
border: 1px solid
@ -121,7 +121,14 @@
.udapp_ataddressinput {
padding: .25rem;
}
.udapp_create {
.udapp_recorderSection:hover {
cursor: pointer;
}.udapp_recorderSectionLabel:hover {
cursor: pointer;
}
.udapp_recorderSectionLabel {
cursor: pointer;
font-size: 1rem;
}
.udapp_input {
font-size: 10px !important;

@ -227,7 +227,8 @@ export interface ContractGUIProps {
clickCallBack: (inputs: { name: string, type: string }[], input: string) => void,
widthClass?: string,
evmBC: any,
lookupOnly: boolean
lookupOnly: boolean,
disabled?: boolean
}
export interface MainnetProps {
network: Network,

@ -9,6 +9,7 @@ import { resetEditorMode, listenToEvents } from './actions/compiler'
import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line
import { getValidLanguage } from '@remix-project/remix-solidity'
import { CopyToClipboard } from '@remix-ui/clipboard'
import { configFileContent } from './compilerConfiguration'
import './css/style.css'
@ -21,10 +22,12 @@ declare global {
const _paq = window._paq = window._paq || [] //eslint-disable-line
export const CompilerContainer = (props: CompilerContainerProps) => {
const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings, isHardhatProject, isTruffleProject } = props // eslint-disable-line
const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings, isHardhatProject, isTruffleProject, workspaceName } = props // eslint-disable-line
const [state, setState] = useState({
hideWarnings: false,
autoCompile: false,
configFilePath: "compiler_config.json",
useFileConfiguration: false,
matomoAutocompileOnce: true,
optimize: false,
compileTimeout: null,
@ -39,13 +42,43 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
language: 'Solidity',
evmVersion: ''
})
const [showFilePathInput, setShowFilePathInput] = useState<boolean>(false)
const [toggleExpander, setToggleExpander] = useState<boolean>(false)
const [disableCompileButton, setDisableCompileButton] = useState<boolean>(false)
const compileIcon = useRef(null)
const promptMessageInput = useRef(null)
const configFilePathInput = useRef(null)
const [hhCompilation, sethhCompilation] = useState(false)
const [truffleCompilation, setTruffleCompilation] = useState(false)
const [compilerContainer, dispatch] = useReducer(compilerReducer, compilerInitialState)
useEffect(() => {
api.setAppParameter('configFilePath', "/compiler_config.json")
api.fileExists("/compiler_config.json").then((exists) => {
if (!exists) createNewConfigFile()
else {
// what to do? discuss
}
})
api.setAppParameter('configFilePath', "/compiler_config.json")
setShowFilePathInput(false)
}, [workspaceName])
useEffect(() => {
const listener = (event) => {
if (configFilePathInput.current !== event.target) {
setShowFilePathInput(false)
return;
}
};
document.addEventListener("mousedown", listener);
document.addEventListener("touchstart", listener);
return () => {
document.removeEventListener("mousedown", listener);
document.removeEventListener("touchstart", listener);
}
})
useEffect(() => {
fetchAllVersion((allversions, selectedVersion, isURL) => {
setState(prevState => {
@ -72,6 +105,10 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const autocompile = await api.getAppParameter('autoCompile') as boolean || false
const hideWarnings = await api.getAppParameter('hideWarnings') as boolean || false
const includeNightlies = await api.getAppParameter('includeNightlies') as boolean || false
const useFileConfiguration = await api.getAppParameter('useFileConfiguration') as boolean || false
let configFilePath = await api.getAppParameter('configFilePath')
if (!configFilePath || configFilePath == '') configFilePath = "/compiler_config.json"
setState(prevState => {
const params = api.getCompilerParameters()
const optimize = params.optimize
@ -84,6 +121,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
hideWarnings: hideWarnings,
autoCompile: autocompile,
includeNightlies: includeNightlies,
useFileConfiguration: useFileConfiguration,
configFilePath: configFilePath,
optimize: optimize,
runs: runs,
evmVersion: (evmVersion !== null) && (evmVersion !== 'null') && (evmVersion !== undefined) && (evmVersion !== 'undefined') ? evmVersion : 'default',
@ -140,12 +179,67 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
}
}, [compilerContainer.editor.mode])
useEffect(() => {
compileTabLogic.setUseFileConfiguration(state.useFileConfiguration)
if (state.useFileConfiguration) compileTabLogic.setConfigFilePath(state.configFilePath)
}, [state.useFileConfiguration])
useEffect(() => {
if (configurationSettings) {
setConfiguration(configurationSettings)
}
}, [configurationSettings])
const toggleConfigType = () => {
setState(prevState => {
api.setAppParameter('useFileConfiguration', !state.useFileConfiguration)
return { ...prevState, useFileConfiguration: !state.useFileConfiguration }
})
}
const openFile = async () => {
api.open(state.configFilePath)
}
const createNewConfigFile = async () => {
let filePath = configFilePathInput.current && configFilePathInput.current.value !== '' ? configFilePathInput.current.value : state.configFilePath
if (!filePath.endsWith('.json')) filePath = filePath + '.json'
await api.writeFile(filePath, configFileContent)
api.setAppParameter('configFilePath', filePath)
setState(prevState => {
return { ...prevState, configFilePath: filePath }
})
compileTabLogic.setConfigFilePath(filePath)
setShowFilePathInput(false)
}
const handleConfigPathChange = async () => {
if (configFilePathInput.current.value !== '') {
if (!configFilePathInput.current.value.endsWith('.json')) configFilePathInput.current.value += '.json'
if (await api.fileExists(configFilePathInput.current.value)) {
api.setAppParameter('configFilePath', configFilePathInput.current.value)
setState(prevState => {
return { ...prevState, configFilePath: configFilePathInput.current.value }
})
compileTabLogic.setConfigFilePath(configFilePathInput.current.value)
setShowFilePathInput(false)
} else {
modal(
'New configuration file', `The file "${configFilePathInput.current.value}" you entered does not exist. Do you want to create a new one?`,
'Create',
async () => await createNewConfigFile(),
'Cancel',
() => {
setShowFilePathInput(false)
}
)
}
}
}
const _retrieveVersion = (version?) => {
if (!version) version = state.selectedVersion
if (version === 'builtin') version = state.defaultVersion
@ -538,14 +632,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
onChangeRuns(settings.runs)
}
const toggleConfigurations = () => {
setToggleExpander(!toggleExpander)
}
return (
<section>
<article>
<header className='remixui_compilerSection border-bottom'>
<div className="mb-2">
<div className='pt-0 remixui_compilerSection'>
<div className="mb-1">
<label className="remixui_compilerLabel form-check-label" htmlFor="versionSelector">
Compiler
<button className="far fa-plus-square border-0 p-0 mx-2 btn-sm" onClick={promptCompiler} title="Add a custom compiler with URL"></button>
<button className="far fa-plus btn-light border-0 p-0 mx-2 btn-sm" onClick={promptCompiler} title="Add a custom compiler with URL"></button>
</label>
<select value={ state.selectedVersion || state.defaultVersion } onChange={(e) => handleLoadVersion(e.target.value) } className="custom-select" id="versionSelector" disabled={state.allversions.length <= 0}>
{ state.allversions.length <= 0 && <option disabled data-id={state.selectedVersion === state.defaultVersion ? 'selected' : ''}>{ state.defaultVersion }</option> }
@ -559,51 +657,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
}
</select>
</div>
<div className="mb-2 remixui_nightlyBuilds custom-control custom-checkbox">
<div className="mb-2 flex-row-reverse remixui_nightlyBuilds custom-control custom-checkbox">
<input className="mr-2 custom-control-input" id="nightlies" type="checkbox" onChange={handleNightliesChange} checked={state.includeNightlies} />
<label htmlFor="nightlies" data-id="compilerNightliesBuild" className="form-check-label custom-control-label">Include nightly builds</label>
</div>
<div className="mb-2">
<label className="remixui_compilerLabel form-check-label" htmlFor="compilierLanguageSelector">Language</label>
<select onChange={(e) => handleLanguageChange(e.target.value)} value={state.language} className="custom-select" id="compilierLanguageSelector" title="Available since v0.5.7">
<option data-id={state.language === 'Solidity' ? 'selected' : ''} value='Solidity'>Solidity</option>
<option data-id={state.language === 'Yul' ? 'selected' : ''} value='Yul'>Yul</option>
</select>
</div>
<div className="mb-2">
<label className="remixui_compilerLabel form-check-label" htmlFor="evmVersionSelector">EVM Version</label>
<select value={state.evmVersion} onChange={(e) => handleEvmVersionChange(e.target.value)} className="custom-select" id="evmVersionSelector">
{compileTabLogic.evmVersions.map((version, index) => (<option key={index} data-id={state.evmVersion === version ? 'selected' : ''} value={version}>{version}</option>))}
</select>
</div>
<div className="mt-3">
<p className="mt-2 remixui_compilerLabel">Compiler Configuration</p>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<input className="remixui_autocompile custom-control-input" type="checkbox" onChange={handleAutoCompile} data-id="compilerContainerAutoCompile" id="autoCompile" title="Auto compile" checked={state.autoCompile} />
<label className="form-check-label custom-control-label" htmlFor="autoCompile">Auto compile</label>
</div>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<div className="justify-content-between align-items-center d-flex">
<input onChange={(e) => { handleOptimizeChange(e.target.checked) }} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimize} />
<label className="form-check-label custom-control-label" htmlFor="optimize">Enable optimization</label>
<input
min="1"
className="custom-select ml-2 remixui_runs"
id="runs"
placeholder="200"
value={state.runs}
type="number"
title="Estimated number of times each opcode of the deployed code will be executed across the life-time of the contract."
onChange={(e) => onChangeRuns(e.target.value)}
disabled={!state.optimize}
/>
</div>
</div>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<div className="mt-1 mb-2 remixui_compilerConfig custom-control custom-checkbox">
<input className="remixui_autocompile custom-control-input" onChange={handleHideWarningsChange} id="hideWarningsBox" type="checkbox" title="Hide warnings" checked={state.hideWarnings} />
<label className="form-check-label custom-control-label" htmlFor="hideWarningsBox">Hide warnings</label>
</div>
</div>
{
isHardhatProject &&
<div className="mt-3 remixui_compilerConfig custom-control custom-checkbox">
@ -636,7 +701,81 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</a>
</div>
}
</div>
<div className="d-flex px-4 remixui_compilerConfigSection justify-content-between" onClick={toggleConfigurations}>
<div className="d-flex">
<label className="mt-1 remixui_compilerConfigSection">Advanced Configurations</label>
</div>
<div>
<span data-id='scConfigExpander' onClick={toggleConfigurations}>
<i className={!toggleExpander ? 'fas fa-angle-right' : 'fas fa-angle-down'} aria-hidden="true"></i>
</span>
</div>
</div>
<div className={`px-4 pb-4 border-bottom flex-column ${toggleExpander ? "d-flex" : "d-none"}`}>
<div className="d-flex pb-1 remixui_compilerConfig custom-control custom-radio">
<input className="custom-control-input" type="radio" name="configradio" value="manual" onChange={toggleConfigType} checked={!state.useFileConfiguration} id="scManualConfig" />
<label className="form-check-label custom-control-label" htmlFor="scManualConfig">Compiler configuration</label>
</div>
<div className={`flex-column 'd-flex'}`}>
<div className="mb-2 ml-4">
<label className="remixui_compilerLabel form-check-label" htmlFor="compilierLanguageSelector">Language</label>
<select onChange={(e) => handleLanguageChange(e.target.value)} disabled={state.useFileConfiguration} value={state.language} className="custom-select" id="compilierLanguageSelector" title="Available since v0.5.7">
<option data-id={state.language === 'Solidity' ? 'selected' : ''} value='Solidity'>Solidity</option>
<option data-id={state.language === 'Yul' ? 'selected' : ''} value='Yul'>Yul</option>
</select>
</div>
<div className="mb-2 ml-4">
<label className="remixui_compilerLabel form-check-label" htmlFor="evmVersionSelector">EVM Version</label>
<select value={state.evmVersion} onChange={(e) => handleEvmVersionChange(e.target.value)} disabled={state.useFileConfiguration} className="custom-select" id="evmVersionSelector">
{compileTabLogic.evmVersions.map((version, index) => (<option key={index} data-id={state.evmVersion === version ? 'selected' : ''} value={version}>{version}</option>))}
</select>
</div>
<div className="mt-1 mt-3 border-dark pb-3 ml-4 remixui_compilerConfig custom-control custom-checkbox">
<div className="justify-content-between align-items-center d-flex">
<input onChange={(e) => { handleOptimizeChange(e.target.checked) }} disabled={state.useFileConfiguration} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimize} />
<label className="form-check-label custom-control-label" htmlFor="optimize">Enable optimization</label>
<input
min="1"
className="custom-select ml-2 remixui_runs"
id="runs"
placeholder="200"
value={state.runs}
type="number"
title="Estimated number of times each opcode of the deployed code will be executed across the life-time of the contract."
onChange={(e) => onChangeRuns(e.target.value)}
disabled={!state.optimize || state.useFileConfiguration}
/>
</div>
</div>
</div>
<div className="d-flex pb-1 remixui_compilerConfig custom-control custom-radio">
<input className="custom-control-input" type="radio" name="configradio" value="file" onChange={toggleConfigType} checked={state.useFileConfiguration} id="scFileConfig" />
<label className="form-check-label custom-control-label" htmlFor="scFileConfig">Use configuration file</label>
</div>
<div className={`pt-2 ml-4 ml-2 align-items-start justify-content-between d-flex`}>
{ (!showFilePathInput && state.useFileConfiguration) && <span
title="Click to open the config file."
onClick={openFile}
className="py-2 text-primary remixui_compilerConfigPath"
>{state.configFilePath}</span> }
{ (!showFilePathInput&& !state.useFileConfiguration) && <span className="py-2 text-secondary">{state.configFilePath}</span> }
<input
ref={configFilePathInput}
className={`py-0 my-0 form-control ${showFilePathInput ? "d-flex" : "d-none"}`}
placeholder={"Enter the new path"}
title="If the file you entered does not exist you will be able to create one in the next step."
disabled={!state.useFileConfiguration}
onKeyPress={event => {
if (event.key === 'Enter') {
handleConfigPathChange()
}
}}
/>
{ !showFilePathInput && <button disabled={!state.useFileConfiguration} className="btn-secondary" onClick={() => {setShowFilePathInput(true)}}>Change</button> }
</div>
</div>
<div className="px-4">
<button id="compileBtn" data-id="compilerContainerCompileBtn" className="btn btn-primary btn-block d-block w-100 text-break remixui_disabled mb-1 mt-3" onClick={compile} disabled={disableCompileButton}>
<OverlayTrigger overlay={
<Tooltip id="overlay-tooltip-compile">
@ -692,7 +831,6 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</CopyToClipboard>
</div>
</div>
</header>
</article>
</section>
)

@ -0,0 +1,18 @@
export const configFileContent = `
{
"language": "Solidity",
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"": ["ast"],
"*": ["abi", "metadata", "devdoc", "userdoc", "storageLayout", "evm.legacyAssembly", "evm.bytecode", "evm.deployedBytecode", "evm.methodIdentifiers", "evm.gasEstimates", "evm.assembly"]
}
},
"evmVersion": "byzantium"
}
}
`

@ -72,6 +72,15 @@
.remixui_compilerSection {
padding: 12px 24px 16px;
}
.remixui_compilerConfigSection:hover {
cursor: pointer;
}
.remixui_compilerConfigSection {
font-size: 1rem;
}
.remixui_compilerConfigPath {
cursor: pointer;
}
.remixui_compilerLabel {
margin-bottom: 2px;
font-size: 11px;

@ -18,6 +18,8 @@ export class CompileTabLogic {
public compilerImport
public event
public evmVersions: Array<string>
public useFileConfiguration: boolean
public configFilePath: string
constructor (public api: ICompilerApi, public contentImport) {
this.event = new EventEmitter()
@ -52,12 +54,21 @@ export class CompileTabLogic {
}
}
setOptimize (newOptimizeValue) {
setOptimize (newOptimizeValue: boolean) {
this.optimize = newOptimizeValue
this.api.setCompilerParameters({ optimize: this.optimize })
this.compiler.set('optimize', this.optimize)
}
setUseFileConfiguration (useFileConfiguration: boolean) {
this.useFileConfiguration = useFileConfiguration
this.compiler.set('useFileConfiguration', useFileConfiguration)
}
setConfigFilePath (path) {
this.configFilePath = path
}
setRuns (runs) {
this.runs = runs
this.api.setCompilerParameters({ runs: this.runs })
@ -95,6 +106,9 @@ export class CompileTabLogic {
const sources = { [target]: { content } }
this.event.emit('removeAnnotations')
this.event.emit('startingCompilation')
this.api.readFile(this.configFilePath).then( contentConfig => {
this.compiler.set('configFileContent', contentConfig)
})
// setTimeout fix the animation on chrome... (animation triggered by 'staringCompilation')
setTimeout(() => { this.compiler.compile(sources, target); resolve(true) }, 100)
}).catch((error) => {

@ -13,6 +13,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
const [state, setState] = useState({
isHardhatProject: false,
isTruffleProject: false,
workspaceName: '',
currentFile,
loading: false,
compileTabLogic: null,
@ -63,11 +64,11 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
})
}
api.onSetWorkspace = async (isLocalhost: boolean) => {
api.onSetWorkspace = async (isLocalhost: boolean, workspaceName: string) => {
const isHardhat = isLocalhost && await compileTabLogic.isHardhatProject()
const isTruffle = await compileTabLogic.isTruffleProject()
setState(prevState => {
return { ...prevState, currentFile, isHardhatProject: isHardhat, isTruffleProject: isTruffle }
return { ...prevState, currentFile, isHardhatProject: isHardhat, workspaceName: workspaceName, isTruffleProject: isTruffle }
})
}
@ -150,7 +151,18 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
return (
<>
<div id="compileTabView">
<CompilerContainer api={api} isHardhatProject={state.isHardhatProject} isTruffleProject={state.isTruffleProject} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} />
<CompilerContainer
api={api}
isHardhatProject={state.isHardhatProject}
workspaceName={state.workspaceName}
isTruffleProject={state.isTruffleProject}
compileTabLogic={compileTabLogic}
tooltip={toast}
modal={modal}
compiledFileName={currentFile}
updateCurrentVersion={updateCurrentVersion}
configurationSettings={configurationSettings}
/>
{ contractsFile[currentFile] && contractsFile[currentFile].contractsDetails && <ContractSelection api={api} contractsDetails={contractsFile[currentFile].contractsDetails} contractList={contractsFile[currentFile].contractList} modal={modal} /> }
{ compileErrors[currentFile] &&
<div className="remixui_errorBlobs p-4" data-id="compiledErrors">

@ -11,6 +11,7 @@ export interface CompilerContainerProps {
compileTabLogic: CompileTabLogic,
isHardhatProject: boolean,
isTruffleProject: boolean,
workspaceName: string,
tooltip: (message: string | JSX.Element) => void,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void,
compiledFileName: string,
@ -45,4 +46,3 @@ export interface CompilationDetails {
export interface ContractsFile {
[currentFile: string]: CompilationDetails
}

@ -4,7 +4,7 @@
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
"allowSyntheticDefaultImports": true,
},
"files": [],
"include": [],

@ -10,7 +10,7 @@ export interface TabsUIProps {
onZoomOut: () => void
onZoomIn: () => void
onReady: (api: any) => void
themeQuality: "dark"
themeQuality: string
}
export interface TabsUIApi {

@ -7,7 +7,7 @@ export const TreeView = (props: TreeViewProps) => {
const { children, id, ...otherProps } = props
return (
<ul data-id={`treeViewUl${id}`} className="ul_tv ml-0 px-2" { ...otherProps }>
<ul data-id={`treeViewUl${id}`} className="ul_tv ml-0 pl-2" { ...otherProps }>
{ children }
</ul>
)

@ -57,7 +57,7 @@ export const FileLabel = (props: FileLabelProps) => {
>
<span
title={file.path}
className={'remixui_label ' + (file.isDirectory ? 'folder' : 'remixui_leaf')}
className={'text-nowrap remixui_label ' + (file.isDirectory ? 'folder' : 'remixui_leaf')}
data-path={file.path}
>
{ file.name }

@ -134,6 +134,8 @@ export function Workspace () {
<option value='remixDefault'>Default</option>
<option value='blank'>Blank</option>
<option value='ozerc20'>OpenZeppelin ERC20</option>
<option value='zeroxErc20'>0xProject ERC20</option>
<option value='ozerc721'>OpenZeppelin ERC721</option>
</select>
</>
)
@ -191,7 +193,7 @@ export function Workspace () {
title='Delete'>
</span>
<span
hidden={currentWorkspace === NO_WORKSPACE}
hidden={currentWorkspace === LOCALHOST || currentWorkspace === NO_WORKSPACE}
id='workspacesDownload'
data-id='workspacesDownload'
onClick={(e) => {
@ -202,6 +204,7 @@ export function Workspace () {
title='Download Workspaces'>
</span>
<span
hidden={currentWorkspace === LOCALHOST}
id='workspacesRestore'
data-id='workspacesRestore'
onClick={(e) => {

@ -12,7 +12,7 @@
`@remix-project/remix-url-resolver` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-url-resolver`
`yarn add @remix-project/remix-url-resolver`
### How to use

@ -8,7 +8,7 @@
`@remix-project/remix-ws-templates` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-ws-templates`
`yarn add @remix-project/remix-ws-templates`
### Contribute

@ -1,3 +1,5 @@
export { default as remixDefault } from './templates/remixDefault'
export { default as ozerc20 } from './templates/ozerc20'
export { default as blank } from './templates/blank'
export { default as ozerc20 } from './templates/ozerc20'
export { default as zeroxErc20 } from './templates/zeroxErc20'
export { default as ozerc721 } from './templates/ozerc721'

@ -3,13 +3,13 @@ export default async () => {
// @ts-ignore
'contracts/SampleERC20.sol': (await import('raw-loader!./contracts/SampleERC20.sol')).default,
// @ts-ignore
'scripts/deploy_with_ethers.ts': (await import('raw-loader!./scripts/deploy_with_ethers.ts')).default,
'scripts/deploy_with_ethers.ts': (await import('!!raw-loader!./scripts/deploy_with_ethers.ts')).default,
// @ts-ignore
'scripts/deploy_with_web3.ts': (await import('raw-loader!./scripts/deploy_with_web3.ts')).default,
'scripts/deploy_with_web3.ts': (await import('!!raw-loader!./scripts/deploy_with_web3.ts')).default,
// @ts-ignore
'scripts/ethers-lib.ts': (await import('raw-loader!./scripts/ethers-lib.ts')).default,
'scripts/ethers-lib.ts': (await import('!!raw-loader!./scripts/ethers-lib.ts')).default,
// @ts-ignore
'scripts/web3-lib.ts': (await import('raw-loader!./scripts/web3-lib.ts')).default,
'scripts/web3-lib.ts': (await import('!!raw-loader!./scripts/web3-lib.ts')).default,
// @ts-ignore
'tests/SampleERC20_test.sol': (await import('raw-loader!./tests/SampleERC20_test.sol')).default
}

@ -1,4 +1,4 @@
import { ethers } from 'ethers-lib'
import { ethers } from 'ethers'
export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => {

@ -1,4 +1,4 @@
import Web3 from 'web3-lib'
import Web3 from 'web3'
export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {

@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
/**
* @title SampleERC721
* @dev Create a sample ERC721 standard token
*/
contract SampleERC721 is ERC721 {
constructor(string memory tokenName, string memory tokenSymbol) ERC721(tokenName, tokenSymbol) {}
}

@ -0,0 +1,16 @@
export default async () => {
return {
// @ts-ignore
'contracts/SampleERC721.sol': (await import('raw-loader!./contracts/SampleERC721.sol')).default,
// @ts-ignore
'scripts/deploy_with_ethers.ts': (await import('!!raw-loader!./scripts/deploy_with_ethers.ts')).default,
// @ts-ignore
'scripts/deploy_with_web3.ts': (await import('!!raw-loader!./scripts/deploy_with_web3.ts')).default,
// @ts-ignore
'scripts/ethers-lib.ts': (await import('!!raw-loader!./scripts/ethers-lib.ts')).default,
// @ts-ignore
'scripts/web3-lib.ts': (await import('!!raw-loader!./scripts/web3-lib.ts')).default,
// @ts-ignore
'tests/SampleERC721_test.sol': (await import('raw-loader!./tests/SampleERC721_test.sol')).default
}
}

@ -0,0 +1,10 @@
import { deploy } from './ethers-lib'
(async () => {
try {
const result = await deploy('SampleERC721', ['testNFT', 'TNFT'])
console.log(`address: ${result.address}`)
} catch (e) {
console.log(e.message)
}
})()

@ -0,0 +1,10 @@
import { deploy } from './web3-lib'
(async () => {
try {
const result = await deploy('SampleERC721', ['testToken', 'TST'])
console.log(`address: ${result.address}`)
} catch (e) {
console.log(e.message)
}
})()

@ -0,0 +1,26 @@
import { ethers } from 'ethers'
export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => {
console.log(`deploying ${contractName}`)
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json`
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
// 'web3Provider' is a remix global variable object
const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner()
const factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer);
let contract
if (from) {
contract = await factory.connect(from).deploy(...args);
} else {
contract = await factory.deploy(...args);
}
// The contract is NOT deployed yet; we must wait until it is mined
await contract.deployed()
return contract
}

@ -0,0 +1,27 @@
import Web3 from 'web3'
export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {
const web3 = new Web3(window.web3Provider)
console.log(`deploying ${contractName}`)
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json`
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
const accounts = await web3.eth.getAccounts()
let contract = new web3.eth.Contract(metadata.abi)
contract = contract.deploy({
data: metadata.data.bytecode.object,
arguments: args
})
const newContractInstance = await contract.send({
from: from || accounts[0],
gas: gas || 1500000
})
return newContractInstance.options
}

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "remix_tests.sol";
import "../contracts/SampleERC721.sol";
contract SampleERC721Test {
SampleERC721 s;
function beforeAll () public {
s = new SampleERC721("TestNFT", "TNFT");
}
function testTokenNameAndSymbol () public {
Assert.equal(s.name(), "TestNFT", "token name did not match");
Assert.equal(s.symbol(), "TNFT", "token symbol did not match");
}
}

@ -7,17 +7,17 @@ export default async () => {
// @ts-ignore
'contracts/3_Ballot.sol': (await import('raw-loader!./contracts/3_Ballot.sol')).default,
// @ts-ignore
'scripts/deploy_with_ethers.ts': (await import('raw-loader!./scripts/deploy_with_ethers.ts')).default,
'scripts/deploy_with_ethers.ts': (await import('!!raw-loader!./scripts/deploy_with_ethers.ts')).default,
// @ts-ignore
'scripts/deploy_with_web3.ts': (await import('raw-loader!./scripts/deploy_with_web3.ts')).default,
'scripts/deploy_with_web3.ts': (await import('!!raw-loader!./scripts/deploy_with_web3.ts')).default,
// @ts-ignore
'scripts/ethers-lib.ts': (await import('raw-loader!./scripts/ethers-lib.ts')).default,
'scripts/ethers-lib.ts': (await import('!!raw-loader!./scripts/ethers-lib.ts')).default,
// @ts-ignore
'scripts/web3-lib.ts': (await import('raw-loader!./scripts/web3-lib.ts')).default,
'scripts/web3-lib.ts': (await import('!!raw-loader!./scripts/web3-lib.ts')).default,
// @ts-ignore
'tests/Ballot_test.sol': (await import('raw-loader!./tests/Ballot_test.sol')).default,
// @ts-ignore
'tests/storage.test.js': (await import('raw-loader!./tests/storage.test.js')).default,
'tests/storage.test.js': (await import('!!raw-loader!./tests/storage.test.js')).default,
// @ts-ignore
'README.txt': (await import('raw-loader!./README.txt')).default,
}

@ -0,0 +1,31 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.5.9;
import "@0x/contracts-erc20/contracts/src/ERC20Token.sol";
/**
* @title SampleERC20
* @dev Create a sample ERC20 standard token
*/
contract SampleERC20 is ERC20Token {
string public name;
string public symbol;
uint256 public decimals;
constructor (
string memory _name,
string memory _symbol,
uint256 _decimals,
uint256 _totalSupply
)
public
{
name = _name;
symbol = _symbol;
decimals = _decimals;
_totalSupply = _totalSupply;
balances[msg.sender] = _totalSupply;
}
}

@ -0,0 +1,16 @@
export default async () => {
return {
// @ts-ignore
'contracts/SampleERC20.sol': (await import('raw-loader!./contracts/SampleERC20.sol')).default,
// @ts-ignore
'scripts/deploy_with_ethers.ts': (await import('!!raw-loader!./scripts/deploy_with_ethers.ts')).default,
// @ts-ignore
'scripts/deploy_with_web3.ts': (await import('!!raw-loader!./scripts/deploy_with_web3.ts')).default,
// @ts-ignore
'scripts/ethers-lib.ts': (await import('!!raw-loader!./scripts/ethers-lib.ts')).default,
// @ts-ignore
'scripts/web3-lib.ts': (await import('!!raw-loader!./scripts/web3-lib.ts')).default,
// @ts-ignore
'tests/SampleERC20_test.sol': (await import('raw-loader!./tests/SampleERC20_test.sol')).default
}
}

@ -0,0 +1,10 @@
import { deploy } from './ethers-lib'
(async () => {
try {
const result = await deploy('SampleERC20', ["TestToken", "TST", 18, 1000])
console.log(`address: ${result.address}`)
} catch (e) {
console.log(e.message)
}
})()

@ -0,0 +1,10 @@
import { deploy } from './web3-lib'
(async () => {
try {
const result = await deploy('SampleERC20', ["TestToken", "TST", 18, 1000])
console.log(`address: ${result.address}`)
} catch (e) {
console.log(e.message)
}
})()

@ -0,0 +1,26 @@
import { ethers } from 'ethers'
export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => {
console.log(`deploying ${contractName}`)
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json`
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
// 'web3Provider' is a remix global variable object
const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner()
const factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer);
let contract
if (from) {
contract = await factory.connect(from).deploy(...args);
} else {
contract = await factory.deploy(...args);
}
// The contract is NOT deployed yet; we must wait until it is mined
await contract.deployed()
return contract
}

@ -0,0 +1,27 @@
import Web3 from 'web3'
export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {
const web3 = new Web3(window.web3Provider)
console.log(`deploying ${contractName}`)
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json`
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
const accounts = await web3.eth.getAccounts()
let contract = new web3.eth.Contract(metadata.abi)
contract = contract.deploy({
data: metadata.data.bytecode.object,
arguments: args
})
const newContractInstance = await contract.send({
from: from || accounts[0],
gas: gas || 1500000
})
return newContractInstance.options
}

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.5.9;
import "remix_tests.sol";
import "../contracts/SampleERC20.sol";
contract SampleERC20Test {
SampleERC20 s;
function beforeAll () public {
s = new SampleERC20("TestToken", "TST", 18, 1000);
}
function testTokenNameAndSymbol () public {
Assert.equal(s.name(), "TestToken", "token name did not match");
Assert.equal(s.symbol(), "TST", "token symbol did not match");
}
}

@ -13,14 +13,14 @@ Alternatively `remixd` can be used to setup a development environment that can b
## INSTALLATION
`npm install -g @remix-project/remixd`
`yarn global add @remix-project/remixd`
### Warning for 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: `npm install -g @remix-project/remixd`
2. install the new: `yarn global add @remix-project/remixd`
## HELP SECTION

@ -1,5 +1,5 @@
{
"watch": ["./src", "./bin"],
"ext": "ts",
"exec": "npm run build && npm run start"
"exec": "yarn run build && yarn run start"
}

@ -18,7 +18,7 @@ async function warnLatestVersion () {
} else if (semver.gt(latest, pjson.version)) {
console.log('\x1b[33m%s\x1b[0m', `[WARN] latest version of remixd is ${latest}, you are using ${pjson.version}`)
console.log('\x1b[33m%s\x1b[0m', '[WARN] please update using the following command:')
console.log('\x1b[33m%s\x1b[0m', '[WARN] npm install @remix-project/remixd -g')
console.log('\x1b[33m%s\x1b[0m', '[WARN] yarn global add @remix-project/remixd')
}
}

48108
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -48,11 +48,11 @@
"lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remix-ws-templates,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,solidity-unit-testing,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs,remix-ui-panel,remix-ui-run-tab,remix-ui-permission-handler,remix-ui-search",
"build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remix-ws-templates,remixd",
"test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"publish:libs": "npm run build:libs && lerna publish --skip-git && npm run bumpVersion:libs",
"publish:libs": "yarn run build:libs && lerna publish --skip-git && yarn run bumpVersion:libs",
"build:e2e": "node apps/remix-ide-e2e/src/buildGroupTests.js && tsc -p apps/remix-ide-e2e/tsconfig.e2e.json",
"watch:e2e": "nodemon",
"bumpVersion:libs": "gulp & gulp syncLibVersions;",
"browsertest": "sleep 5 && npm run nightwatch_local",
"browsertest": "sleep 5 && yarn run nightwatch_local",
"csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='apps/remix-ide/src/assets/css/font-awesome.min.css' apps/remix-ide/src/assets/css/",
"downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/remix-ide/src/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/solidity-compiler/src/assets/js/soljson.js",
"downloadsolc_assets_dist": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./dist/apps/remix-ide/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./dist/apps/solidity-compiler/assets/js/soljson.js",
@ -61,44 +61,44 @@
"build:production": "NODE_ENV=production nx build remix-ide --skip-nx-cache",
"serve:production": "npx http-server ./dist/apps/remix-ide",
"select_test": "sh apps/remix-ide-e2e/src/select_tests.sh",
"group_test": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/${npm_config_test}_group${npm_config_group}.test.js --env=${npm_config_env}",
"nightwatch_parallel": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome,firefox",
"nightwatch_local_firefox": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=firefox",
"nightwatch_local_chrome": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome",
"nightwatch_local_ballot": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot.test.js --env=chrome",
"nightwatch_local_ballot_0_4_11": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.js --env=chrome",
"nightwatch_local_usingWorker": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/usingWebWorker.test.js --env=chrome",
"nightwatch_local_libraryDeployment": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/libraryDeployment.test.js --env=chrome",
"nightwatch_local_solidityImport": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityImport_*.test.js --env=chrome",
"nightwatch_local_recorder": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/recorder.test.js --env=chrome",
"nightwatch_local_transactionExecution": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/transactionExecution_*.test.js --env=chrome",
"nightwatch_local_staticAnalysis": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/staticAnalysis.test.js --env=chrome",
"nightwatch_local_signingMessage": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/signingMessage.test.js --env=chrome",
"nightwatch_local_specialFunctions": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/specialFunctions_*.test.js --env=chrome",
"nightwatch_local_solidityUnitTests": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityUnittests_*.test.js --env=chrome",
"nightwatch_local_remixd": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/remixd.test.js --env=chrome",
"nightwatch_local_terminal": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/terminal_*.test.js --env=chrome",
"nightwatch_local_gist": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/gist.test.js --env=chrome",
"nightwatch_local_workspace": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/workspace.test.js --env=chrome",
"nightwatch_local_defaultLayout": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/defaultLayout.test.js --env=chrome",
"nightwatch_local_pluginManager": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/pluginManager.test.js --env=chrome",
"nightwatch_local_publishContract": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/publishContract.test.js --env=chrome",
"nightwatch_local_generalSettings": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/generalSettings.test.js --env=chrome",
"nightwatch_local_fileExplorer": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileExplorer.test.js --env=chrome",
"nightwatch_local_debugger": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.test.js --env=chrome",
"nightwatch_local_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/editor.test.js --env=chrome",
"nightwatch_local_importFromGithub": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/importFromGithub.test.js --env=chrome",
"nightwatch_local_compiler": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/compiler_api.test.js --env=chrome",
"nightwatch_local_txListener": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/txListener.test.js --env=chrome",
"nightwatch_local_fileManager": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileManager_api.test.js --env=chrome",
"nightwatch_local_runAndDeploy": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/runAndDeploy.js --env=chrome-runAndDeploy",
"nightwatch_local_url": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/url.test.js --env=chrome",
"nightwatch_local_verticalIconscontextmenu": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/verticalIconsPanel.test.js --env=chrome",
"nightwatch_local_pluginApi": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/plugin_api_*.js --env=chrome",
"nightwatch_local_migrate_filesystem": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/migrateFileSystem.test.js --env=chrome",
"nightwatch_local_stress_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stressEditor.test.js --env=chromeDesktop",
"nightwatch_local_search": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/search.test.js --env=chromeDesktop",
"nightwatch_local_providers": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/providers.test.js --env=chromeDesktop",
"group_test": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/${npm_config_test}_group${npm_config_group}.test.js --env=${npm_config_env}",
"nightwatch_parallel": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome,firefox",
"nightwatch_local_firefox": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=firefox",
"nightwatch_local_chrome": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome",
"nightwatch_local_ballot": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot.test.js --env=chrome",
"nightwatch_local_ballot_0_4_11": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.js --env=chrome",
"nightwatch_local_usingWorker": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/usingWebWorker.test.js --env=chrome",
"nightwatch_local_libraryDeployment": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/libraryDeployment.test.js --env=chrome",
"nightwatch_local_solidityImport": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityImport_*.test.js --env=chrome",
"nightwatch_local_recorder": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/recorder.test.js --env=chrome",
"nightwatch_local_transactionExecution": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/transactionExecution_*.test.js --env=chrome",
"nightwatch_local_staticAnalysis": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/staticAnalysis.test.js --env=chrome",
"nightwatch_local_signingMessage": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/signingMessage.test.js --env=chrome",
"nightwatch_local_specialFunctions": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/specialFunctions_*.test.js --env=chrome",
"nightwatch_local_solidityUnitTests": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityUnittests_*.test.js --env=chrome",
"nightwatch_local_remixd": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/remixd.test.js --env=chrome",
"nightwatch_local_terminal": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/terminal_*.test.js --env=chrome",
"nightwatch_local_gist": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/gist.test.js --env=chrome",
"nightwatch_local_workspace": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/workspace.test.js --env=chrome",
"nightwatch_local_defaultLayout": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/defaultLayout.test.js --env=chrome",
"nightwatch_local_pluginManager": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/pluginManager.test.js --env=chrome",
"nightwatch_local_publishContract": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/publishContract.test.js --env=chrome",
"nightwatch_local_generalSettings": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/generalSettings.test.js --env=chrome",
"nightwatch_local_fileExplorer": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileExplorer.test.js --env=chrome",
"nightwatch_local_debugger": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.test.js --env=chrome",
"nightwatch_local_editor": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/editor.test.js --env=chrome",
"nightwatch_local_importFromGithub": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/importFromGithub.test.js --env=chrome",
"nightwatch_local_compiler": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/compiler_api.test.js --env=chrome",
"nightwatch_local_txListener": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/txListener.test.js --env=chrome",
"nightwatch_local_fileManager": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileManager_api.test.js --env=chrome",
"nightwatch_local_runAndDeploy": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/runAndDeploy.js --env=chrome-runAndDeploy",
"nightwatch_local_url": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/url.test.js --env=chrome",
"nightwatch_local_verticalIconscontextmenu": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/verticalIconsPanel.test.js --env=chrome",
"nightwatch_local_pluginApi": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/plugin_api_*.js --env=chrome",
"nightwatch_local_migrate_filesystem": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/migrateFileSystem.test.js --env=chrome",
"nightwatch_local_stress_editor": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stressEditor.test.js --env=chromeDesktop",
"nightwatch_local_search": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/search.test.js --env=chromeDesktop",
"nightwatch_local_providers": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/providers.test.js --env=chromeDesktop",
"onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint",
"remixd": "nx build remixd && chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js -s ./apps/remix-ide/contracts --remix-ide http://127.0.0.1:8080",
"selenium": "selenium-standalone start",
@ -106,7 +106,7 @@
"sourcemap": "exorcist --root ../ apps/remix-ide/build/app.js.map > apps/remix-ide/build/app.js",
"test-browser": "npm-run-all -lpr selenium make-mock-compiler serve browsertest",
"watch": "watchify apps/remix-ide/src/index.js -dv -p browserify-reload -o apps/remix-ide/build/app.js --exclude solc",
"reinstall": "rm ./node-modules/ -rf && rm package-lock.json && rm ./build/ -rf && npm install & npm run build",
"reinstall": "rm ./node-modules/ -rf && rm package-lock.json && rm ./build/ -rf && yarn install & yarn run build",
"ganache-cli": "npx ganache-cli"
},
"browserify": {

@ -64,6 +64,42 @@ The release manager is still responsible for ensuring a project is rolled out sm
- During feature freeze, remix-beta should be updated every morning.
- A meeting with Andy and Rob should be organized for ensuring the beta test results are properly handled.
## check list:
### pre release planning
- [ ] create a new project and prioritize issues / bugs with the team lead and according to the current roadmap.
- [ ] check with the team lead if this needs an intermediate release (intermediate release should be 2-3 weeks max).
- [ ] a release kickoff meeting with the team aiming to get input from everyone and modify the project accordingly.
- [ ] 2-3 days span where team members estimate their issues.
- [ ] a release planning meeting where we agree on the release scope (intermediate and/or classic release).
- [ ] after this meeting: all the issues / PR should have been qualified in term of effort and scope.
- [ ] after this meeting: date for feature freeze, QA period, and release date should be set in the project title.
### coding period
- [ ] 10 min after each daily standup where the release manager give an update of the current situation and ETA.
- [ ] release manager should make sure to be aware of the current state of each issues and PRs during the coding period in order to have a better overview of who is working on what and best provide support to all the team members that are involved in the release.
### QA preparation
- [ ] prepare the internal QA document, assign team members.
- [ ] prepare the external beta test document for beta testers.
- [ ] 1 week before QA period, start engaging with beta testers and online.
### feature freeze, QA period.
- [ ] publish to remix-beta every day.
- [ ] merge reviewed PRs.
- [ ] a QA open sync meeting where we all do our assigned tasks.
### post release
- [ ] retrospective meeting.
## Assignments:
Aniket, Liana, David, Rob, Filip, Yann

@ -20,7 +20,7 @@ This document includes:
- git fetch origin master
- git checkout origin/master
- git checkout -b bumpLibsVersion
- npm run publish:libs (this command uses lerna)
- yarn run publish:libs (this command uses lerna)
- commit
## Remix IDE release Part 1. First push master to beta. Feature Freeze

24426
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save