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

pull/4837/head
filip mertens 7 months ago
commit 9402f800f6
  1. 96
      .circleci/config.yml
  2. 2
      .github/workflows/pr-reminder.yml
  3. 1
      .gitignore
  4. 22
      README.md
  5. 4
      apps/etherscan/src/app/utils/networks.ts
  6. 4
      apps/learneth/README.md
  7. 42
      apps/remix-ide-e2e/install-webdriver.sh
  8. 46
      apps/remix-ide-e2e/nightwatch-chrome.ts
  9. 54
      apps/remix-ide-e2e/nightwatch-firefox.ts
  10. 1
      apps/remix-ide-e2e/package.json
  11. 74
      apps/remix-ide-e2e/src/commands/addFileSnekmate.ts
  12. 22
      apps/remix-ide-e2e/src/commands/selectFiles.ts
  13. 69
      apps/remix-ide-e2e/src/commands/setupMetamask.ts
  14. 1
      apps/remix-ide-e2e/src/commands/switchBrowserTab.ts
  15. BIN
      apps/remix-ide-e2e/src/extensions/chrome/11.13.1_0.crx
  16. BIN
      apps/remix-ide-e2e/src/extensions/chrome/metamask.crx
  17. 2
      apps/remix-ide-e2e/src/helpers/init.ts
  18. 19
      apps/remix-ide-e2e/src/select_tests.sh
  19. 107
      apps/remix-ide-e2e/src/tests/circom.test.ts
  20. 27
      apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts
  21. 106
      apps/remix-ide-e2e/src/tests/pinned_contracts.test.ts
  22. 128
      apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts
  23. 272
      apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts
  24. 2
      apps/remix-ide-e2e/src/tests/sol2uml.test.ts
  25. 1
      apps/remix-ide-e2e/src/tests/staticAnalysis.test.ts
  26. 3
      apps/remix-ide-e2e/src/tests/transactionExecution.test.ts
  27. 233
      apps/remix-ide-e2e/src/tests/vyper_api.test.ts
  28. 25
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  29. 2
      apps/remix-ide-e2e/src/types/index.d.ts
  30. 597
      apps/remix-ide-e2e/yarn.lock
  31. 2
      apps/remix-ide/ci/browser_test.sh
  32. 2
      apps/remix-ide/ci/browser_test_plugin.sh
  33. 2
      apps/remix-ide/ci/flaky.sh
  34. 28
      apps/remix-ide/src/app.js
  35. 244
      apps/remix-ide/src/app/plugins/remixGuide.tsx
  36. 48
      apps/remix-ide/src/app/plugins/solcoderAI.tsx
  37. 2
      apps/remix-ide/src/app/providers/abstract-provider.tsx
  38. 20
      apps/remix-ide/src/app/providers/injected-custom-provider.tsx
  39. 12
      apps/remix-ide/src/app/providers/injected-provider-default.tsx
  40. 2
      apps/remix-ide/src/app/tabs/locale-module.js
  41. 2
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  42. 6
      apps/remix-ide/src/app/tabs/locales/en/remixUiTabs.json
  43. 12
      apps/remix-ide/src/app/tabs/locales/en/udapp.json
  44. 15
      apps/remix-ide/src/app/tabs/locales/ru/circuit.json
  45. 26
      apps/remix-ide/src/app/tabs/locales/ru/debugger.json
  46. 134
      apps/remix-ide/src/app/tabs/locales/ru/filePanel.json
  47. 69
      apps/remix-ide/src/app/tabs/locales/ru/home.json
  48. 17
      apps/remix-ide/src/app/tabs/locales/ru/index.js
  49. 10
      apps/remix-ide/src/app/tabs/locales/ru/panel.json
  50. 13
      apps/remix-ide/src/app/tabs/locales/ru/permissionHandler.json
  51. 43
      apps/remix-ide/src/app/tabs/locales/ru/pluginManager.json
  52. 3
      apps/remix-ide/src/app/tabs/locales/ru/remixApp.json
  53. 7
      apps/remix-ide/src/app/tabs/locales/ru/remixUiTabs.json
  54. 24
      apps/remix-ide/src/app/tabs/locales/ru/search.json
  55. 44
      apps/remix-ide/src/app/tabs/locales/ru/settings.json
  56. 81
      apps/remix-ide/src/app/tabs/locales/ru/solidity.json
  57. 41
      apps/remix-ide/src/app/tabs/locales/ru/solidityUnitTesting.json
  58. 43
      apps/remix-ide/src/app/tabs/locales/ru/terminal.json
  59. 139
      apps/remix-ide/src/app/tabs/locales/ru/udapp.json
  60. 123
      apps/remix-ide/src/app/udapp/run-tab.js
  61. 13
      apps/remix-ide/src/assets/css/themes/bootstrap-cerulean.min.css
  62. 15
      apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css
  63. 13
      apps/remix-ide/src/assets/css/themes/bootstrap-flatly.min.css
  64. 13
      apps/remix-ide/src/assets/css/themes/bootstrap-spacelab.min.css
  65. 1
      apps/remix-ide/src/assets/css/themes/remix-black_undtds.css
  66. 14
      apps/remix-ide/src/assets/css/themes/remix-candy_ikhg4m.css
  67. 1
      apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css
  68. 1
      apps/remix-ide/src/assets/css/themes/remix-hacker_owl.css
  69. 12
      apps/remix-ide/src/assets/css/themes/remix-light_powaqg.css
  70. 12
      apps/remix-ide/src/assets/css/themes/remix-midcentury_hrzph3.css
  71. 12
      apps/remix-ide/src/assets/css/themes/remix-unicorn.css
  72. 12
      apps/remix-ide/src/assets/css/themes/remix-violet.css
  73. 39
      apps/remix-ide/src/blockchain/blockchain.tsx
  74. 4
      apps/remix-ide/src/blockchain/providers/injected.ts
  75. 4
      apps/remix-ide/src/blockchain/providers/node.ts
  76. 4
      apps/remix-ide/src/blockchain/providers/vm.ts
  77. 32
      apps/remix-ide/src/remixAppManager.js
  78. 9
      apps/vyper/src/app/app.tsx
  79. 3
      apps/vyper/src/app/components/CompileErrorCard.tsx
  80. 17
      apps/vyper/src/app/components/CompilerButton.tsx
  81. 21
      apps/vyper/src/app/utils/compiler.tsx
  82. 8
      apps/vyper/src/app/utils/remix-client.tsx
  83. 8
      libs/ghaction-helper/package.json
  84. 8
      libs/remix-analyzer/package.json
  85. 6
      libs/remix-astwalker/package.json
  86. 12
      libs/remix-debug/package.json
  87. 2
      libs/remix-debug/src/cmdline/index.ts
  88. 2
      libs/remix-debug/src/solidity-decoder/decodeInfo.ts
  89. 6
      libs/remix-debug/src/storage/storageViewer.ts
  90. 3
      libs/remix-debug/src/trace/traceAnalyser.ts
  91. 4
      libs/remix-lib/package.json
  92. 2
      libs/remix-lib/src/execution/txExecution.ts
  93. 15
      libs/remix-lib/src/execution/txRunnerVM.ts
  94. 19
      libs/remix-lib/src/execution/txRunnerWeb3.ts
  95. 6
      libs/remix-simulator/package.json
  96. 6
      libs/remix-solidity/package.json
  97. 4
      libs/remix-solidity/src/compiler/compiler-abstract.ts
  98. 10
      libs/remix-tests/package.json
  99. 2
      libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
  100. 6
      libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-locals.tsx
  101. Some files were not shown because too many files have changed in this diff Show More

@ -598,6 +598,13 @@ jobs:
type: string
parallelism: 10
steps:
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- run: yarn install --cwd ./apps/remix-ide-e2e --modules-folder ../../node_modules || yarn install --cwd ./apps/remix-ide-e2e --modules-folder ../../node_modules
- run: mkdir node_modules/hardhat && wget https://unpkg.com/hardhat/console.sol -O node_modules/hardhat/console.sol
- run: ls -la ./dist/apps/remix-ide/assets/js
- when:
condition:
equal: [ "chrome", << parameters.browser >> ]
@ -607,10 +614,8 @@ jobs:
install-chrome: true
install-chromedriver: false
install-geckodriver: false
- install-chromedriver-custom-linux
- run: yarn install_webdriver
- run: google-chrome --version
- run: chromedriver --version
- run: rm LICENSE.chromedriver 2> /dev/null || true
- when:
condition:
equal: [ "firefox", << parameters.browser >> ]
@ -618,36 +623,10 @@ jobs:
- browser-tools/install-browser-tools:
install-firefox: true
install-chrome: false
install-geckodriver: true
install-geckodriver: false
install-chromedriver: false
- run: yarn install_webdriver
- run: firefox --version
- run: geckodriver --version
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- run: yarn install --cwd ./apps/remix-ide-e2e --modules-folder ../../node_modules
- run: mkdir node_modules/hardhat && wget https://unpkg.com/hardhat/console.sol -O node_modules/hardhat/console.sol
- run: ls -la ./dist/apps/remix-ide/assets/js
- run: yarn run selenium-install --singleDriverInstall=firefox
- when:
condition:
equal: [ "chrome", << parameters.browser >> ]
steps:
- run: mkdir -p node_modules/selenium-standalone/.selenium/chromedriver/latest-x64/
- run: cp ~/bin/chromedriver /home/circleci/remix-project/node_modules/selenium-standalone/.selenium/chromedriver/latest-x64/
- run:
name: run selenium
command: yarn selenium-standalone start --singleDriverStart=chrome
background: true
- when:
condition:
equal: [ "firefox", << parameters.browser >> ]
steps:
- run:
name: run selenium
command: yarn selenium-standalone start --singleDriverStart=firefox
background: true
- run: ./apps/remix-ide/ci/<< parameters.script >> << parameters.browser >> << parameters.jobsize >> << parameters.job >>
- store_test_results:
path: ./reports/tests
@ -674,28 +653,19 @@ jobs:
default: 1
parallelism: << parameters.parallelism >>
steps:
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- run: unzip ./persist/plugin-<< parameters.plugin >>.zip
- run: yarn install --cwd ./apps/remix-ide-e2e --modules-folder ../../node_modules || yarn install --cwd ./apps/remix-ide-e2e --modules-folder ../../node_modules
- browser-tools/install-browser-tools:
install-firefox: false
install-chrome: true
install-geckodriver: false
install-chromedriver: false
- install-chromedriver-custom-linux
- run: yarn install_webdriver
- run: google-chrome --version
- run: chromedriver --version
- run: rm LICENSE.chromedriver 2> /dev/null || true
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- run: unzip ./persist/plugin-<< parameters.plugin >>.zip
- run: yarn install --cwd ./apps/remix-ide-e2e --modules-folder ../../node_modules
- run: yarn run selenium-install --singleDriverInstall=firefox
- run: mkdir -p node_modules/selenium-standalone/.selenium/chromedriver/latest-x64/
- run: cp ~/bin/chromedriver /home/circleci/remix-project/node_modules/selenium-standalone/.selenium/chromedriver/latest-x64/
- run:
name: Start Selenium
command: yarn run selenium --singleDriverStart=chrome
background: true
- run: ./apps/remix-ide/ci/browser_test_plugin.sh << parameters.plugin >>
- store_test_results:
path: ./reports/tests
@ -882,35 +852,3 @@ workflows:
only: remix_beta
# VS Code Extension Version: 1.5.1
commands:
install-chromedriver-custom-linux:
description: Custom script to install chromedriver with better version support for linux
steps:
- run:
name: install-chromedriver-custom-linux
command: |
google-chrome --version > version.txt
VERSION=$(grep -Eo '[0-9]+\.' < version.txt | head -1)
# CHROMEDRIVER_URL=$(curl -s 'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json' | jq '.channels.Stable.downloads.chromedriver[] | select(.platform == "linux64") | .url' | tr -d '"')
CHROMEDRIVER_URL=$(curl -s 'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json' | jq --arg v "$VERSION" '.versions[] | select(.version | startswith($v)) | .downloads.chromedriver[] | select(.platform == "linux64") | .url' | tail -n1 | tr -d '"')
echo $CHROMEDRIVER_URL
ZIPFILEPATH="/tmp/chromedriver.zip"
echo "Downloading from $CHROMEDRIVER_URL"
curl -f --silent $CHROMEDRIVER_URL > "$ZIPFILEPATH"
BINFILEPATH="$HOME/bin/chromedriver-linux"
echo "Extracting to $BINFILEPATH"
unzip -p "$ZIPFILEPATH" chromedriver-linux64/chromedriver > "$BINFILEPATH"
echo Setting execute flag
chmod +x "$BINFILEPATH"
echo Updating symlink
ln -nfs "$BINFILEPATH" ~/bin/chromedriver
echo Removing ZIP file
rm "$ZIPFILEPATH"
rm version.txt
echo Done
chromedriver -v

@ -14,4 +14,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
freeze-date: '2024-04-08T18:00:00Z'
freeze-date: '2024-04-22T18:00:00Z'

1
.gitignore vendored

@ -68,3 +68,4 @@ apps/remix-ide/src/assets/esbuild.wasm
apps/remixdesktop/build*
apps/remixdesktop/reports
apps/remixdesktop/logs/
logs

@ -146,21 +146,11 @@ For example, to run unit tests of `remix-analyzer`, use `nx test remix-analyzer`
## Browser Testing
To run the Selenium tests via Nightwatch:
To run the tests via Nightwatch:
- Install Selenium for the first time: `yarn run selenium-install`
- Run a selenium server: `yarn run selenium`
- Install webdrivers for the first time: `yarn install_webdriver`
- Build & Serve Remix: `yarn serve`
- Run all the end-to-end tests:
for Firefox: `yarn run nightwatch_local_firefox`, or
for Google Chrome: `yarn run nightwatch_local_chrome`
- Run a specific test case instead, use a command like this:
- yarn run nightwatch_local_ballot
The package.json file contains a list of all the tests you can run.
**NOTE:**
@ -173,8 +163,6 @@ To run the Selenium tests via Nightwatch:
gist_token = <token> // token should have permission to create a gist
```
### Using 'select_test' for locally running specific tests
There is a script to allow selecting the browser and a specific test to run:
```
@ -246,12 +234,6 @@ This script will give you an options menu, just select the test you want
```
yarn run select_test
```
#### method 2
```
yarn run group_test --test=debugger --group=10 --env=chromeDesktop
```
- specify chromeDesktop to see the browser action, use 'chrome' to run it headless
### Run the same (flaky) test across all instances in CircleCI

@ -17,9 +17,10 @@ export const scanAPIurls = {
1101: 'https://api-zkevm.polygonscan.com/api',
59144: 'https://api.lineascan.build/api',
8453: 'https://api.basescan.org/api',
534352: 'https://api.scrollscan.com/api',
// all testnet
5: 'https://api-goerli.etherscan.io/api',
17000: 'https://api-holesky.etherscan.io/api',
11155111: 'https://api-sepolia.etherscan.io/api',
97: 'https://api-testnet.bscscan.com/api',
80001: 'https://api-testnet.polygonscan.com/api',
@ -37,4 +38,5 @@ export const scanAPIurls = {
84532: "https://api-sepolia.basescan.org/api",
1442: 'https://api-testnet-zkevm.polygonscan.com/api',
59140: 'https://api-testnet.lineascan.build/api',
534351: 'https://api-sepolia.scrollscan.com/api',
}

@ -42,11 +42,11 @@ Root directories are individual workshops, the name used will be the name of the
### README.md
The readme in each directry contains an explanation of what the workshop is about. If an additional summary property is provided in the config.yml that will be used in the overview section of the plugin.
The readme in each directory contains an explanation of what the workshop is about. If an additional summary property is provided in the config.yml that will be used in the overview section of the plugin.
### config.yml
This config file contains meta data describing some properties of your workshop, for example
This config file contains metadata describing some properties of your workshop, for example
```
---

@ -0,0 +1,42 @@
#!/bin/bash
# Determine the OS platform
OS="$(uname)"
if [ "$OS" == "Darwin" ]; then
# macOS systems
if [ -e "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ]; then
version=$("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --version)
echo "Google Chrome version on macOS: $version"
else
echo "Google Chrome is not installed on your macOS."
fi
elif [ "$OS" == "Linux" ]; then
# Linux systems
if command -v google-chrome >/dev/null; then
version=$(google-chrome --version)
echo "Google Chrome version on Linux: $version"
else
echo "Google Chrome is not installed on your Linux."
fi
else
echo "Unsupported OS."
fi
MAJORVERSION=$(echo "$version" | grep -Eo '[0-9]+\.' | head -1 | cut -d'.' -f1)
echo "CHROME DRIVER INSTALL $MAJORVERSION"
# Specify the directory to check
directory="./tmp/webdrivers"
# Check if the directory exists
if [ -d "$directory" ]; then
echo "Directory exists: $directory"
else
echo "Directory does not exist. Creating directory: $directory"
mkdir -p "$directory"
fi
yarn init -y --cwd "$directory" || exit 1
yarn add -D chromedriver@$MAJORVERSION geckodriver --cwd "$directory" || yarn add -D chromedriver@$MAJORVERSION geckodriver --cwd "$directory" || yarn add -D chromedriver geckodriver --cwd "$directory" || exit 1

@ -1,3 +1,8 @@
import * as fs from 'fs'
const crxFile = fs.readFileSync('apps/remix-ide-e2e/src/extensions/chrome/11.13.1_0.crx')
const metamaskExtension = crxFile.toString('base64')
module.exports = {
src_folders: ['dist/apps/remix-ide-e2e/src/tests'],
output_folder: './reports/tests',
@ -6,10 +11,14 @@ module.exports = {
page_objects_path: '',
globals_path: '',
webdriver: {
start_process: true,
port: 9515,
server_path: './tmp/webdrivers/node_modules/chromedriver/bin/chromedriver',
},
test_settings: {
'default': {
selenium_port: 4444,
selenium_host: 'localhost',
globals: {
waitForConditionTimeout: 10000,
asyncHookTimeout: 100000
@ -31,12 +40,12 @@ module.exports = {
'goog:chromeOptions': {
args: [
'window-size=2560,1440',
'start-fullscreen',
'--no-sandbox',
'--headless',
'--headless=new',
'--verbose',
'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
]
],
extensions: [metamaskExtension]
}
}
},
@ -47,40 +56,31 @@ module.exports = {
'javascriptEnabled': true,
'acceptSslCerts': true,
'goog:chromeOptions': {
args: ['window-size=2560,1440', 'start-fullscreen', '--no-sandbox']
args: ['window-size=2560,1440', 'start-fullscreen', '--no-sandbox', '--verbose']
}
}
},
'chrome-runAndDeploy': {
'chromeDesktopMetamask': {
desiredCapabilities: {
'browserName': 'chrome',
'javascriptEnabled': true,
'acceptSslCerts': true,
'goog:chromeOptions': {
args: ['window-size=2560,1440', 'start-fullscreen', '--no-sandbox', '--headless', '--verbose']
args: ['window-size=2560,1440', '--no-sandbox', '--verbose']
,extensions: [metamaskExtension]
}
}
},
'firefoxDesktop': {
desiredCapabilities: {
'browserName': 'firefox',
'javascriptEnabled': true,
'acceptSslCerts': true,
'moz:firefoxOptions': {
args: ['-width=2560', '-height=1440']
}
}
},
'firefox': {
'chrome-runAndDeploy': {
desiredCapabilities: {
'browserName': 'firefox',
'browserName': 'chrome',
'javascriptEnabled': true,
'acceptSslCerts': true,
'moz:firefoxOptions': {
args: ['-headless', '-width=2560', '-height=1440']
'goog:chromeOptions': {
args: ['window-size=2560,1440', 'start-fullscreen', '--no-sandbox', '--headless', '--verbose'],
extensions: [metamaskExtension]
}
}
}

@ -0,0 +1,54 @@
module.exports = {
src_folders: ['dist/apps/remix-ide-e2e/src/tests'],
output_folder: './reports/tests',
custom_commands_path: ['dist/apps/remix-ide-e2e/src/commands'],
custom_assertions_path: '',
page_objects_path: '',
globals_path: '',
webdriver: {
start_process: true,
port: 4444,
server_path: './tmp/webdrivers/node_modules/geckodriver/bin/geckodriver.js',
},
test_settings: {
selenium_port: 4444,
selenium_host: 'localhost',
'default': {
globals: {
waitForConditionTimeout: 10000,
asyncHookTimeout: 100000
},
screenshots: {
enabled: true,
path: './reports/screenshots',
on_failure: true,
on_error: true
},
exclude: ['dist/apps/remix-ide-e2e/src/tests/runAndDeploy.test.js', 'dist/apps/remix-ide-e2e/src/tests/pluginManager.test.ts']
},
'firefoxDesktop': {
desiredCapabilities: {
'browserName': 'firefox',
'javascriptEnabled': true,
'acceptSslCerts': true,
'moz:firefoxOptions': {
args: ['-width=2560', '-height=1440']
}
}
},
'firefox': {
desiredCapabilities: {
'browserName': 'firefox',
'javascriptEnabled': true,
'acceptSslCerts': true,
'moz:firefoxOptions': {
args: ['-headless', '-width=2560', '-height=1440']
}
}
}
}
}

@ -12,7 +12,6 @@
"@openzeppelin/wizard": "^0.4.0",
"@remix-project/remixd": "../../dist/libs/remixd",
"deep-equal": "^1.0.1",
"selenium-standalone": "^9.0.3",
"tree-kill": "^1.2.2"
},
"devDependencies": {

@ -0,0 +1,74 @@
import EventEmitter from 'events'
import { NightwatchBrowser, NightwatchContractContent } from 'nightwatch'
class AddFileSnekmate extends EventEmitter {
command(this: NightwatchBrowser, name: string, content: NightwatchContractContent): NightwatchBrowser {
this.api.perform((done) => {
addFileSnekmate(this.api, name, content, () => {
done()
this.emit('complete')
})
})
return this
}
}
function addFileSnekmate(browser: NightwatchBrowser, name: string, content: NightwatchContractContent, done: VoidFunction) {
browser
.isVisible({
selector: "//*[@data-id='sidePanelSwapitTitle' and contains(.,'File explorer')]",
locateStrategy: 'xpath',
suppressNotFoundErrors: true,
timeout: 1000
}, (okVisible) => {
if (!okVisible.value) {
browser.clickLaunchIcon('filePanel')
}
})
.scrollInto('li[data-id="treeViewLitreeViewItemREADME.txt"]')
.waitForElementVisible('li[data-id="treeViewLitreeViewItemLICENSE"]')
.click('li[data-id="treeViewLitreeViewItemLICENSE"]').pause(1000) // focus on root directory
.isVisible({
selector: `//*[@data-id="treeViewLitreeViewItem${name}"]`,
locateStrategy: 'xpath',
abortOnFailure: false,
suppressNotFoundErrors: true,
timeout: 2000
}, (okVisible) => {
// @ts-ignore
// status === -1 means the element is not visible, 0 means it is visible.
if (okVisible.status === 0) {
browser.openFile(name)
.perform(function () {
done()
})
} else {
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="fileExplorerTreeItemInput"]', '', 60000)
.sendKeys('*[data-id$="fileExplorerTreeItemInput"]', name)
.sendKeys('*[data-id$="fileExplorerTreeItemInput"]', browser.Keys.ENTER)
// isvisible is protocol action called isDisplayed https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/WebElement.html#isDisplayed--
.isVisible({
selector: `li[data-id="treeViewLitreeViewItem${name}"]`,
abortOnFailure: false,
suppressNotFoundErrors: true,
timeout: 60000
})
.waitForElementVisible({
selector: `//*[@data-id='tab-active' and contains(@data-path, "${name}")]`,
locateStrategy: 'xpath'
})
.setEditorValue(content.content)
.getEditorValue((result) => {
if(result != content.content) {
browser.setEditorValue(content.content)
}
})
.perform(function () {
done()
})
}
})
}
module.exports = AddFileSnekmate

@ -0,0 +1,22 @@
import EventEmitter from "events"
import { NightwatchBrowser } from "nightwatch"
class SelectFiles extends EventEmitter {
command (this: NightwatchBrowser, selectedElements: any[]): NightwatchBrowser {
const browser = this.api
browser.perform(function () {
const actions = this.actions({ async: true })
actions.keyDown(this.Keys.SHIFT)
for(let i = 0; i < selectedElements.length; i++) {
actions.click(selectedElements[i].value)
}
return actions.contextClick(selectedElements[0].value)
})
this.emit('complete')
return this
}
}
module.exports = SelectFiles

@ -3,7 +3,7 @@ import { NightwatchBrowser } from 'nightwatch'
const EventEmitter = require('events')
class MetaMask extends EventEmitter {
command (this: NightwatchBrowser, passphrase: string, password: string): NightwatchBrowser {
command(this: NightwatchBrowser, passphrase: string, password: string): NightwatchBrowser {
this.api.perform((done) => {
setupMetaMask(this.api, passphrase, password, () => {
done()
@ -14,27 +14,60 @@ class MetaMask extends EventEmitter {
}
}
function setupMetaMask (browser: NightwatchBrowser, passphrase: string, password: string, done: VoidFunction) {
function setupMetaMask(browser: NightwatchBrowser, passphrase: string, password: string, done: VoidFunction) {
const words = passphrase.split(' ')
browser
.switchBrowserWindow('chrome-extension://poemojpkcjbpmcccohjnomjffeinlafe/home.html#initialize/welcome', 'MetaMask', (browser) => {
browser.waitForElementPresent('.first-time-flow__button')
.click('.first-time-flow__button')
.waitForElementPresent('.select-action__select-button:nth-of-type(1) > .first-time-flow__button')
.click('.select-action__select-button:nth-of-type(1) > .first-time-flow__button')
.waitForElementPresent('.page-container__footer-button:nth-of-type(2)')
.click('.page-container__footer-button:nth-of-type(2)')
.waitForElementPresent('.first-time-flow__textarea')
.setValue('.first-time-flow__textarea', passphrase)
.setValue('*[autocomplete="new-password"]', password)
.setValue('*[autocomplete="confirm-password"]', password)
.click('.first-time-flow__checkbox')
.click('.first-time-flow__button')
.pause(5000)
.click('.first-time-flow__button')
.switchBrowserTab(1)
.waitForElementVisible('input[data-testid="onboarding-terms-checkbox"]')
.click('input[data-testid="onboarding-terms-checkbox"]')
.waitForElementVisible('button[data-testid="onboarding-import-wallet"]')
.click('button[data-testid="onboarding-import-wallet"]')
.waitForElementVisible('button[data-testid="metametrics-i-agree"]')
.click('button[data-testid="metametrics-i-agree"]')
.waitForElementVisible('input[data-testid="import-srp__srp-word-0"]')
.setValue('input[data-testid="import-srp__srp-word-0"]', words[0]) // import account
.setValue('input[data-testid="import-srp__srp-word-1"]', words[1]) // import account
.setValue('input[data-testid="import-srp__srp-word-2"]', words[2]) // import account
.setValue('input[data-testid="import-srp__srp-word-3"]', words[3]) // import account
.setValue('input[data-testid="import-srp__srp-word-4"]', words[4]) // import account
.setValue('input[data-testid="import-srp__srp-word-5"]', words[5]) // import account
.setValue('input[data-testid="import-srp__srp-word-6"]', words[6]) // import account
.setValue('input[data-testid="import-srp__srp-word-7"]', words[7]) // import account
.setValue('input[data-testid="import-srp__srp-word-8"]', words[8]) // import account
.setValue('input[data-testid="import-srp__srp-word-9"]', words[9]) // import account
.setValue('input[data-testid="import-srp__srp-word-10"]', words[10]) // import account
.setValue('input[data-testid="import-srp__srp-word-11"]', words[11]) // import account
.click('button[data-testid="import-srp-confirm"]')
.waitForElementVisible('input[data-testid="create-password-new"]')
.setValue('input[data-testid="create-password-new"]', password)
.setValue('input[data-testid="create-password-confirm"]', password)
.click('input[data-testid="create-password-terms"]')
.click('button[data-testid="create-password-import"]')
.waitForElementVisible('button[data-testid="onboarding-complete-done"]')
.click('button[data-testid="onboarding-complete-done"]')
.waitForElementVisible('button[data-testid="pin-extension-next"]')
.click('button[data-testid="pin-extension-next"]')
.waitForElementVisible('button[data-testid="pin-extension-done"]')
.click('button[data-testid="pin-extension-done"]')
.isVisible({
selector: 'button[data-testid="popover-close"]',
locateStrategy: 'css selector',
suppressNotFoundErrors: true,
timeout: 3000
}, (okVisible) => {
console.log('okVisible', okVisible)
if (!okVisible.value) {
console.log('popover not found')
}else{
browser.click('button[data-testid="popover-close"]')
}
})
.click('[data-testid="network-display"]')
.click('.mm-modal-content label.toggle-button--off') // show test networks
.click('div[data-testid="Sepolia"]') // switch to sepolia
.perform(() => {
done()
})
})
}
module.exports = MetaMask

@ -9,6 +9,7 @@ class SwitchBrowserTab extends EventEmitter {
command (this: NightwatchBrowser, index: number): NightwatchBrowser {
this.api.perform((browser: NightwatchAPI, done) => {
browser.windowHandles((result) => {
console.log('switching to window', result)
browser.switchWindow(result.value[index])
done()
})

@ -10,6 +10,8 @@ type LoadPlugin = {
export default function (browser: NightwatchBrowser, callback: VoidFunction, url?: string, preloadPlugins = true, loadPlugin?: LoadPlugin, hideToolTips: boolean = true): void {
browser
.url(url || 'http://127.0.0.1:8080')
.pause(5000)
.switchBrowserTab(0)
.perform((done) => {
if (!loadPlugin) return done()
browser

@ -3,7 +3,7 @@
# Bash Menu Script Example
PS3='Select a browser: '
BROWSERS=( "chrome" "chrome headless" "firefox" "exit" )
BROWSERS=( "chrome" "chrome with metamask" "firefox" "exit" )
select opt in "${BROWSERS[@]}"
do
case $opt in
@ -12,9 +12,9 @@ do
BROWSER="chromeDesktop"
break
;;
"chrome headless")
echo "Chrome headless selected"
BROWSER="chrome"
"chrome with metamask")
echo "Chrome metamask selected"
BROWSER="chromeDesktopMetamask"
break
;;
"firefox")
@ -47,6 +47,15 @@ do
done
else
# run the selected test
yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $opt --env=$BROWSER
if [ "$BROWSER" = "firefoxDesktop" ]; then
yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch-firefox.js $opt --env=$BROWSER
elif [ "$BROWSER" = "chrome" ]; then
yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch-chrome.js $opt --env=$BROWSER
elif [ "$BROWSER" = "chromeDesktop" ]; then
yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch-chrome.js $opt --env=$BROWSER
elif [ "$BROWSER" = "chromeDesktopMetamask" ]; then
yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch-chrome.js $opt --env=$BROWSER
fi
fi
done

@ -23,9 +23,15 @@ module.exports = {
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits/semaphore.circom"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/run_setup.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/groth16"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/groth16/groth16_trusted_setup.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/groth16/groth16_zkproof.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/plonk"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/plonk/plonk_trusted_setup.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/plonk/plonk_zkproof.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates/groth16_verifier.sol.ejs"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates/plonk_verifier.sol.ejs"]')
},
'Should compile a simple circuit using editor play button #group1': function (browser: NightwatchBrowser) {
browser
@ -143,6 +149,105 @@ module.exports = {
.frameParent()
.clickLaunchIcon('filePanel')
.waitForElementPresent('[data-id="treeViewLitreeViewItemcircuits/.bin/simple.wasm"]')
},
'Should create a new workspace using hash checker template #group5 #group6': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=hashchecker]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits/calculate_hash.circom"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/groth16"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/groth16/groth16_trusted_setup.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/groth16/groth16_zkproof.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/plonk"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/plonk/plonk_trusted_setup.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/plonk/plonk_zkproof.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates/groth16_verifier.sol.ejs"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates/plonk_verifier.sol.ejs"]')
},
'Should run groth16 trusted setup script for hash checker #group5': function (browser: NightwatchBrowser) {
browser
.click('[data-id="treeViewLitreeViewItemscripts/groth16/groth16_trusted_setup.ts"]')
.waitForElementPresent('[data-path="Hash Checker - 1/scripts/groth16/groth16_trusted_setup.ts"]')
.waitForElementVisible('[data-path="Hash Checker - 1/scripts/groth16/groth16_trusted_setup.ts"]')
.waitForElementPresent('[data-id="verticalIconsKindcircuit-compiler"]')
.waitForElementVisible('[data-id="verticalIconsKindcircuit-compiler"]')
.click('[data-id="play-editor"]')
.pause(2000)
.journalLastChildIncludes('Generating R1CS for circuits/calculate_hash.circom')
.pause(5000)
.journalLastChildIncludes('Everything went okay')
.journalLastChildIncludes('newZkey')
.pause(25000)
.journalLastChildIncludes('setup done.')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemzk/keys/groth16/verification_key.json"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemzk/keys/groth16/zkey_final.txt"]')
},
'Should run groth16 zkproof script for hash checker #group5': function (browser: NightwatchBrowser) {
browser
.click('[data-id="treeViewLitreeViewItemscripts/groth16/groth16_zkproof.ts"]')
.waitForElementPresent('[data-path="Hash Checker - 1/scripts/groth16/groth16_zkproof.ts"]')
.waitForElementVisible('[data-path="Hash Checker - 1/scripts/groth16/groth16_zkproof.ts"]')
.waitForElementPresent('[data-id="verticalIconsKindcircuit-compiler"]')
.waitForElementVisible('[data-id="verticalIconsKindcircuit-compiler"]')
.click('[data-id="play-editor"]')
.pause(2000)
.journalLastChildIncludes('Compiling circuits/calculate_hash.circom')
.pause(5000)
.journalLastChildIncludes('Everything went okay')
.journalLastChildIncludes('WITNESS CHECKING STARTED')
.pause(5000)
.journalLastChildIncludes('WITNESS CHECKING FINISHED SUCCESSFULLY')
.pause(2000)
.journalLastChildIncludes('zk proof validity')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemzk/build/groth16/zk_verifier.sol"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemzk/build/groth16/input.json"]')
},
'Should run plonk trusted setup script for hash checker #group6': function (browser: NightwatchBrowser) {
browser
.click('[data-id="treeViewLitreeViewItemscripts/plonk/plonk_trusted_setup.ts"]')
.waitForElementPresent('[data-path="Hash Checker - 1/scripts/plonk/plonk_trusted_setup.ts"]')
.waitForElementVisible('[data-path="Hash Checker - 1/scripts/plonk/plonk_trusted_setup.ts"]')
.waitForElementPresent('[data-id="verticalIconsKindcircuit-compiler"]')
.waitForElementVisible('[data-id="verticalIconsKindcircuit-compiler"]')
.click('[data-id="play-editor"]')
.pause(2000)
.journalLastChildIncludes('Generating R1CS for circuits/calculate_hash.circom')
.pause(5000)
.journalLastChildIncludes('Everything went okay')
.journalLastChildIncludes('plonk setup')
.pause(10000)
.journalLastChildIncludes('setup done')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemzk/keys/plonk/verification_key.json"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemzk/keys/plonk/zkey_final.txt"]')
},
'Should run plonk zkproof script for hash checker #group6': function (browser: NightwatchBrowser) {
browser
.click('[data-id="treeViewLitreeViewItemscripts/plonk/plonk_zkproof.ts"]')
.waitForElementPresent('[data-path="Hash Checker - 1/scripts/plonk/plonk_zkproof.ts"]')
.waitForElementVisible('[data-path="Hash Checker - 1/scripts/plonk/plonk_zkproof.ts"]')
.waitForElementPresent('[data-id="verticalIconsKindcircuit-compiler"]')
.waitForElementVisible('[data-id="verticalIconsKindcircuit-compiler"]')
.click('[data-id="play-editor"]')
.pause(2000)
.journalLastChildIncludes('Compiling circuits/calculate_hash.circom')
.pause(5000)
.journalLastChildIncludes('Everything went okay')
.pause(5000)
.journalLastChildIncludes('zk proof validity')
.journalLastChildIncludes('proof done.')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemzk/build/plonk/zk_verifier.sol"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemzk/build/plonk/input.json"]')
}
}

@ -0,0 +1,27 @@
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},
'Should select multiple items in file explorer #group1': function (browser: NightwatchBrowser) {
const selectedElements = []
browser
.openFile('contracts')
.click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' })
.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]', locateStrategy: 'xpath' }, (el) => {
selectedElements.push(el)
})
browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' },
(el: any) => {
selectedElements.push(el)
})
browser.selectFiles(selectedElements)
.assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]')
.assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]')
.assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemtests"]')
.end()
}
}

@ -0,0 +1,106 @@
'use strict'
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},
'Should show text in pinned contracts section #group1': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('udapp')
.assert.elementPresent('*[data-id="pinnedContracts"]')
.assert.textContains('*[data-id="pinnedContractsSublabel"]', '(network: vm-cancun)')
.assert.elementPresent('*[data-id="NoPinnedInstanceText"]')
.assert.textContains('*[data-id="NoPinnedInstanceText"]', 'No pinned contracts found for selected workspace & network')
},
'Deploy & pin contract #group1': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('filePanel')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]')
.click('*[data-id="treeViewLitreeViewItemcontracts"]')
.click('*[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]')
.clickLaunchIcon('udapp')
.click('*[data-id="Deploy - transact (not payable)"]')
.assert.elementPresent('*[data-id="unpinnedInstance0xd9145CCE52D386f254917e481eB44e9943F39138"]')
.click('*[data-id="universalDappUiUdappPin"]')
.assert.elementPresent('*[data-id="deployAndRunNoInstanceText"]')
.assert.textContains('*[data-id="deployAndRunNoInstanceText"]', 'Currently you have no unpinned contracts to interact with.')
.assert.not.elementPresent('*[data-id="NoPinnedInstanceText"]')
.assert.elementPresent('*[data-id="pinnedInstance0xd9145CCE52D386f254917e481eB44e9943F39138"]')
},
'Test pinned contract loading on environment change #group1': function (browser: NightwatchBrowser) {
browser
.switchEnvironment('vm-shanghai')
.assert.elementPresent('*[data-id="pinnedContracts"]')
.assert.textContains('*[data-id="pinnedContractsSublabel"]', '(network: vm-shanghai)')
.assert.elementPresent('*[data-id="NoPinnedInstanceText"]')
.assert.textContains('*[data-id="NoPinnedInstanceText"]', 'No pinned contracts found for selected workspace & network')
.switchEnvironment('vm-cancun')
.assert.textContains('*[data-id="pinnedContractsSublabel"]', '(network: vm-cancun)')
.assert.not.elementPresent('*[data-id="NoPinnedInstanceText"]')
.assert.elementPresent('*[data-id="pinnedInstance0xd9145CCE52D386f254917e481eB44e9943F39138"]')
},
'Interact with pinned contract #group1': function (browser: NightwatchBrowser) {
browser
.click('*[data-id="universalDappUiTitleExpander0"]')
.assert.elementPresent('*[data-id="instanceContractBal"]')
.assert.elementPresent('*[data-id="instanceContractPinnedAt"]')
.assert.elementPresent('*[data-id="instanceContractFilePath"]')
.assert.textContains('*[data-id="instanceContractFilePath"]', 'default_workspace/contracts/1_Storage.sol')
.clickFunction('retrieve - call')
.testFunction('last',
{
to: 'Storage.retrieve() 0xd9145CCE52D386f254917e481eB44e9943F39138',
'decoded output': { "0": "uint256: 0" }
})
.clickFunction('store - transact (not payable)', { types: 'uint256 num', values: '35' })
.testFunction('last',
{
status: '0x1 Transaction mined and execution succeed',
'decoded input': { "uint256 num": "35" }
})
.clickFunction('retrieve - call')
.testFunction('last',
{
to: 'Storage.retrieve() 0xd9145CCE52D386f254917e481eB44e9943F39138',
'decoded output': { "0": "uint256: 35" }
})
},
'Unpin & interact #group1': function (browser: NightwatchBrowser) {
browser
.click('*[data-id="universalDappUiUdappUnpin"]')
.assert.textContains('*[data-id="NoPinnedInstanceText"]', 'No pinned contracts found for selected workspace & network')
.assert.not.elementPresent('*[data-id="deployAndRunNoInstanceText"]')
.click('*[data-id="universalDappUiTitleExpander0"]')
.assert.not.elementPresent('*[data-id="instanceContractPinnedAt"]')
.assert.not.elementPresent('*[data-id="instanceContractFilePath"]')
.clickFunction('retrieve - call')
.testFunction('last',
{
to: 'Storage.retrieve() 0xd9145CCE52D386f254917e481eB44e9943F39138',
'decoded output': { "0": "uint256: 35" }
})
.clickFunction('store - transact (not payable)', { types: 'uint256 num', values: '55' })
.testFunction('last',
{
status: '0x1 Transaction mined and execution succeed',
'decoded input': { "uint256 num": "55" }
})
.clickFunction('retrieve - call')
.testFunction('last',
{
to: 'Storage.retrieve() 0xd9145CCE52D386f254917e481eB44e9943F39138',
'decoded output': { "0": "uint256: 55" }
})
},
'Re-pin & delete immediately #group1': function (browser: NightwatchBrowser) {
browser
.click('*[data-id="universalDappUiUdappPin"]')
.assert.elementPresent('*[data-id="deployAndRunNoInstanceText"]')
.click('*[data-id="universalDappUiUdappDelete"]')
.assert.textContains('*[data-id="NoPinnedInstanceText"]', 'No pinned contracts found for selected workspace & network')
.assert.textContains('*[data-id="deployAndRunNoInstanceText"]', 'Currently you have no unpinned contracts to interact with.')
},
}

@ -2,9 +2,6 @@
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
const passphrase = process.env.account_passphrase
const password = process.env.account_password
module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
@ -115,131 +112,6 @@ module.exports = {
.end()
},
'Should connect to Goerli Test Network using MetaMask': !function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.setupMetamask(passphrase, password)
.click('.network-indicator__down-arrow')
.useXpath().click("//span[text()='Goerli Test Network']")
.useCss().switchBrowserTab(0)
.refreshPage()
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.click('*[data-id="landingPageStartSolidity"]')
.pause(5000)
.clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="settingsSelectEnvOptions"]')
.click('*[data-id="settingsSelectEnvOptions"] option[id="injected-mode"]')
.waitForElementPresent('*[data-id="settingsNetworkEnv"]')
.assert.containsText('*[data-id="settingsNetworkEnv"]', 'Goerli (5) network')
.switchBrowserTab(2)
.waitForElementPresent('.page-container__footer-button:nth-of-type(2)')
.click('.page-container__footer-button:nth-of-type(2)')
.switchBrowserTab(0)
},
'Should deploy contract on Goerli Test Network using MetaMask': !function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="runTabSelectAccount"] option')
.clickLaunchIcon('filePanel')
.openFile('Greet.sol')
.clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="Deploy - transact (not payable)"]')
.click('*[data-id="Deploy - transact (not payable)"]')
.switchBrowserTab(2)
.waitForElementPresent('.transaction-status--unapproved')
.click('.transaction-status--unapproved')
.waitForElementPresent('.page-container__footer-button:nth-of-type(2)')
.click('.page-container__footer-button:nth-of-type(2)')
.waitForElementPresent('.transaction-status--submitted')
.pause(25000)
.switchBrowserTab(0)
},
'Should run low level interaction (fallback function) on Goerli Test Network using MetaMask': !function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.waitForElementPresent('*[data-id="universalDappUiTitleExpander"]')
.click('*[data-id="universalDappUiTitleExpander"]')
.waitForElementPresent('*[data-id="pluginManagerSettingsDeployAndRunLLTxSendTransaction"]')
.click('*[data-id="pluginManagerSettingsDeployAndRunLLTxSendTransaction"]')
.switchBrowserTab(2)
.waitForElementPresent('.transaction-status--unapproved')
.click('.transaction-status--unapproved')
.waitForElementPresent('.page-container__footer-button:nth-of-type(2)')
.click('.page-container__footer-button:nth-of-type(2)')
.waitForElementPresent('.transaction-status--submitted')
.pause(25000)
.switchBrowserTab(0)
.end()
},
'Should connect to Ethereum Main Network using MetaMask': !function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.switchBrowserTab(2)
.waitForElementPresent('.network-indicator__down-arrow')
.click('.network-indicator__down-arrow')
.useXpath().click("//span[text()='Main Ethereum Network']")
.useCss().switchBrowserTab(0)
.refreshPage()
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.click('*[data-id="landingPageStartSolidity"]')
.pause(5000)
.clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="settingsSelectEnvOptions"]')
.click('*[data-id="settingsSelectEnvOptions"] option[id="injected-mode"]')
.waitForElementPresent('*[data-id="settingsNetworkEnv"]')
.assert.containsText('*[data-id="settingsNetworkEnv"]', 'Main (1) network')
},
'Should deploy contract on Ethereum Main Network using MetaMask': !function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="runTabSelectAccount"] option')
.clickLaunchIcon('filePanel')
.openFile('Greet.sol')
.clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="Deploy - transact (not payable)"]')
.click('*[data-id="Deploy - transact (not payable)"]')
.waitForElementPresent('*[data-id="modalDialogContainer"]', 15000)
.pause(10000)
.assert.containsText('*[data-id="modalDialogModalBody"]', 'You are creating a transaction on the main network. Click confirm if you are sure to continue.')
.modalFooterCancelClick()
},
/*
* This test is using 3 different services:
* - Metamask for getting the transaction
* - Source Verifier service for fetching the contract code
* - Ropsten node for retrieving the trace and storage
*
*/
'Should debug Ropsten transaction with source highlighting using the source verifier service and MetaMask': !function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.switchBrowserTab(2)
.waitForElementPresent('.network-indicator__down-arrow')
.click('.network-indicator__down-arrow')
.useXpath().click("//span[text()='Ropsten Test Network']") // switch to Ropsten
.useCss().switchBrowserTab(0)
.refreshPage()
.clickLaunchIcon('pluginManager') // load debugger and source verification
// .scrollAndClick('#pluginManager article[id="remixPluginManagerListItem_sourcify"] button')
// debugger already activated .scrollAndClick('#pluginManager article[id="remixPluginManagerListItem_debugger"] button')
.clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="settingsSelectEnvOptions"]')
.click('*[data-id="settingsSelectEnvOptions"] option[id="injected-mode"]') // switch to Ropsten in udapp
.waitForElementPresent('*[data-id="settingsNetworkEnv"]')
.assert.containsText('*[data-id="settingsNetworkEnv"]', 'Ropsten (3) network')
.clickLaunchIcon('debugger')
.setValue('*[data-id="debuggerTransactionInput"]', '0x959371506b8f6223d71c709ac2eb2d0158104dca2d76ca949f1662712cf0e6db') // debug tx
.click('*[data-id="debuggerTransactionStartButton"]')
.waitForElementVisible('*[data-id="treeViewDivto"]', 30000)
.assert.containsText('*[data-id="stepdetail"]', 'loaded address:\n0x3c943Fb816694d7D1f4C738e3e7823818a88DD6C')
.assert.containsText('*[data-id="solidityLocals"]', 'to: 0x6C3CCC7FBA111707D5A1AAF2758E9D4F4AC5E7B1')
},
'Call web3.eth.getAccounts() using Injected Provider (Metamask)': !function (browser: NightwatchBrowser) {
browser
.executeScriptInTerminal('web3.eth.getAccounts()')
.journalLastChildIncludes('[ "0x76a3ABb5a12dcd603B52Ed22195dED17ee82708f" ]')
.end()
},
'Should ensure that save environment state is checked by default #group4 #group5': function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.clickLaunchIcon('settings')

@ -0,0 +1,272 @@
'use strict'
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
const passphrase = process.env.account_passphrase
const password = process.env.account_password
const extension_id = 'nkbihfbeogaeaoehlefnkodbefgpgknn'
const extension_url = `chrome-extension://${extension_id}/home.html`
const checkBrowserIsChrome = function (browser: NightwatchBrowser) {
return browser.browserName.indexOf('chrome') > -1
}
const checkAlerts = function (browser: NightwatchBrowser){
browser.isVisible({
selector: '//*[contains(.,"not have enough")]',
locateStrategy: 'xpath',
suppressNotFoundErrors: true,
timeout: 3000
}, (okVisible) => {
if (okVisible.value) {
browser.assert.fail('Not enough ETH in test account!!')
browser.end()
}
})
}
module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},
'@sources': function () {
return sources
},
'Should connect to Sepolia Test Network using MetaMask #group1': function (browser: NightwatchBrowser) {
if (!checkBrowserIsChrome(browser)) return
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.setupMetamask(passphrase, password)
.useCss().switchBrowserTab(0)
.refreshPage()
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.click('*[data-id="landingPageStartSolidity"]')
.clickLaunchIcon('udapp')
.switchEnvironment('injected-MetaMask')
.waitForElementPresent('*[data-id="settingsNetworkEnv"]')
.assert.containsText('*[data-id="settingsNetworkEnv"]', 'Sepolia (11155111) network')
.pause(5000)
.switchBrowserWindow(extension_url, 'MetaMask', (browser) => {
browser
.waitForElementVisible('*[data-testid="page-container-footer-next"]')
.click('*[data-testid="page-container-footer-next"]') // this connects the metamask account to remix
.pause(2000)
.waitForElementVisible('*[data-testid="page-container-footer-next"]')
.click('*[data-testid="page-container-footer-next"]')
// .waitForElementVisible('*[data-testid="popover-close"]')
// .click('*[data-testid="popover-close"]')
})
.switchBrowserTab(0) // back to remix
},
'Should add a contract file #group1': function (browser: NightwatchBrowser) {
if (!checkBrowserIsChrome(browser)) return
browser.waitForElementVisible('*[data-id="remixIdeSidePanel"]')
.clickLaunchIcon('filePanel')
.addFile('Greet.sol', sources[0]['Greet.sol'])
.clickLaunchIcon('udapp')
.waitForElementVisible('*[data-id="Deploy - transact (not payable)"]', 45000) // wait for the contract to compile
},
'Should deploy contract on Sepolia Test Network using MetaMask #group1': function (browser: NightwatchBrowser) {
if (!checkBrowserIsChrome(browser)) return
browser.clearConsole().waitForElementPresent('*[data-id="runTabSelectAccount"] option', 45000)
.clickLaunchIcon('filePanel')
.openFile('Greet.sol')
.clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="Deploy - transact (not payable)"]')
.click('*[data-id="Deploy - transact (not payable)"]')
.pause(5000)
.perform((done) => {
browser.switchBrowserWindow(extension_url, 'MetaMask', (browser) => {
checkAlerts(browser)
browser
.waitForElementPresent('[data-testid="page-container-footer-next"]')
.click('[data-testid="page-container-footer-next"]') // approve the tx
.switchBrowserTab(0) // back to remix
.waitForElementContainsText('*[data-id="terminalJournal"]', 'view on etherscan', 60000)
.waitForElementContainsText('*[data-id="terminalJournal"]', 'from: 0x76a...2708f', 60000)
.perform(() => done())
})
})
},
'Should run low level interaction (fallback function) on Sepolia Test Network using MetaMask #group1': function (browser: NightwatchBrowser) {
if (!checkBrowserIsChrome(browser)) return
browser.clearConsole().waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.clickInstance(0)
.waitForElementPresent('*[data-id="pluginManagerSettingsDeployAndRunLLTxSendTransaction"]')
.click('*[data-id="pluginManagerSettingsDeployAndRunLLTxSendTransaction"]')
.perform((done) => {
browser.switchBrowserWindow(extension_url, 'MetaMask', (browser) => {
browser
.waitForElementPresent('[data-testid="page-container-footer-next"]')
.click('[data-testid="page-container-footer-next"]') // approve the tx
.switchBrowserTab(0) // back to remix
.waitForElementContainsText('*[data-id="terminalJournal"]', 'view on etherscan', 60000)
.waitForElementContainsText('*[data-id="terminalJournal"]', 'from: 0x76a...2708f', 60000)
.perform(() => done())
})
})
},
'Should connect to Ethereum Main Network using MetaMask #group1': function (browser: NightwatchBrowser) {
if (!checkBrowserIsChrome(browser)) return
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.switchBrowserTab(1)
.click('[data-testid="network-display"]')
.click('div[data-testid="Ethereum Mainnet"]') // switch to mainnet
.useCss().switchBrowserTab(0)
.refreshPage()
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.click('*[data-id="landingPageStartSolidity"]')
.clickLaunchIcon('udapp')
.switchEnvironment('injected-MetaMask')
.waitForElementPresent('*[data-id="settingsNetworkEnv"]')
.assert.containsText('*[data-id="settingsNetworkEnv"]', 'Main (1) network')
},
'Should deploy contract on Ethereum Main Network using MetaMask #group1': function (browser: NightwatchBrowser) {
if (!checkBrowserIsChrome(browser)) return
browser.waitForElementPresent('*[data-id="runTabSelectAccount"] option')
.clickLaunchIcon('filePanel')
.openFile('Greet.sol')
.clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="Deploy - transact (not payable)"]')
.click('*[data-id="Deploy - transact (not payable)"]')
.waitForElementVisible('*[data-id="udappNotifyModalDialogModalBody-react"]', 65000)
.modalFooterOKClick('udappNotify')
.pause(10000)
.assert.containsText('*[data-id="udappNotifyModalDialogModalBody-react"]', 'You are about to create a transaction on Main Network. Confirm the details to send the info to your provider.')
.modalFooterCancelClick('udappNotify')
},
'Should deploy Ballot to Sepolia using metamask': function (browser: NightwatchBrowser) {
if (!checkBrowserIsChrome(browser)) return
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.switchBrowserTab(1)
.click('[data-testid="network-display"]')
.click('div[data-testid="Sepolia"]') // switch to sepolia
.useCss().switchBrowserTab(0)
.openFile('contracts')
.openFile('contracts/3_Ballot.sol')
.clickLaunchIcon('udapp')
.clearConsole()
.clearTransactions()
.clickLaunchIcon('udapp')
.waitForElementVisible('input[placeholder="bytes32[] proposalNames"]')
.setValue('input[placeholder="bytes32[] proposalNames"]', '["0x48656c6c6f20576f726c64210000000000000000000000000000000000000000"]')
.click('*[data-id="Deploy - transact (not payable)"]') // deploy ballot
.perform((done) => {
browser.switchBrowserWindow(extension_url, 'MetaMask', (browser) => {
browser
.waitForElementPresent('[data-testid="page-container-footer-next"]')
.click('[data-testid="page-container-footer-next"]') // approve the tx
.switchBrowserTab(0) // back to remix
.waitForElementContainsText('*[data-id="terminalJournal"]', 'view on etherscan', 60000)
.waitForElementContainsText('*[data-id="terminalJournal"]', 'from: 0x76a...2708f', 60000)
.perform(() => done())
})
})
.waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]', 60000)
.clearConsole()
.clickInstance(0)
.clickFunction('delegate - transact (not payable)', { types: 'address to', values: '"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db"' })
.perform((done) => { // call delegate
browser.switchBrowserWindow(extension_url, 'MetaMask', (browser) => {
browser
.waitForElementPresent('[data-testid="page-container-footer-next"]')
.click('[data-testid="page-container-footer-next"]') // approve the tx
.switchBrowserTab(0) // back to remix
.waitForElementContainsText('*[data-id="terminalJournal"]', 'view on etherscan', 60000)
.waitForElementContainsText('*[data-id="terminalJournal"]', 'from: 0x76a...2708f', 60000)
.perform(() => done())
})
})
.testFunction('last',
{
status: '0x1 Transaction mined and execution succeed',
'decoded input': { 'address to': '0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB' }
})
},
/*
* This test is using 2 different services:
* - Metamask for getting the transaction
* - Sepolia node for retrieving the trace and storage
*/
'Should debug Sepolia transaction with source highlighting MetaMask #group1': function (browser: NightwatchBrowser) {
if (!checkBrowserIsChrome(browser)) return
let txhash
browser.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.clickLaunchIcon('pluginManager') // load debugger and source verification
// .scrollAndClick('#pluginManager article[id="remixPluginManagerListItem_sourcify"] button')
// debugger already activated .scrollAndClick('#pluginManager article[id="remixPluginManagerListItem_debugger"] button')
.clickLaunchIcon('udapp')
.perform((done) => {
browser.getLastTransactionHash((hash) => {
txhash = hash
done()
})
})
.perform((done) => {
browser
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.clickLaunchIcon('debugger')
.setValue('*[data-id="debuggerTransactionInput"]', txhash) // debug tx
.click('*[data-id="debuggerTransactionStartButton"]')
.waitForElementVisible('*[data-id="treeViewDivto"]', 30000)
.checkVariableDebug('soliditylocals', localsCheck)
.perform(() => done())
})
},
'Call web3.eth.getAccounts() using Injected Provider (Metamask) #group1': function (browser: NightwatchBrowser) {
if (!checkBrowserIsChrome(browser)) return
browser
.executeScriptInTerminal('web3.eth.getAccounts()')
.journalLastChildIncludes('["0x76a3ABb5a12dcd603B52Ed22195dED17ee82708f"]')
}
}
const localsCheck = {
to: {
value: '0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB',
type: 'address'
}
}
const sources = [
{
'Greet.sol': {
content:
`
pragma solidity ^0.8.0;
contract HelloWorld {
string public message;
fallback () external {
message = 'Hello World!';
}
function greet(string memory _message) public {
message = _message;
}
}`
},
'checkBalance.sol': {
content: `pragma solidity ^0.8.0;
contract CheckBalance {
constructor () payable {}
function sendSomeEther(uint256 num) public {
payable(msg.sender).transfer(num);
}
}`
}
}
]

@ -210,5 +210,5 @@ contract SampleERC20 is ERC20Token {
}
`}
}
}
]

@ -46,7 +46,6 @@ module.exports = {
.waitForElementPresent('//*[@id="staticanalysisresult"]', 5000)
.useCss()
// Check warning count
.pause()
.waitForElementVisible('span#ssaRemixtab')
.click('span#ssaRemixtab')
.assert.containsText('span#ssaRemixtab > *[data-id="RemixStaticAnalysisErrorCount"]', '1')

@ -174,7 +174,6 @@ module.exports = {
.journalLastChildIncludes('"documentation": "param1"')
.journalLastChildIncludes('"documentation": "param2"')
.journalLastChildIncludes('"documentation": "param3"')
.journalLastChildIncludes('Debug the transaction to get more information.')
.click('*[data-id="deployAndRunClearInstances"]')
},
@ -198,7 +197,6 @@ module.exports = {
.journalLastChildIncludes('"documentation": "param1"')
.journalLastChildIncludes('"documentation": "param2"')
.journalLastChildIncludes('"documentation": "param3"')
.journalLastChildIncludes('Debug the transaction to get more information.')
},
'Should Compile and Deploy a contract which define a custom error in a library, the error should be logged in the terminal #group3': function (browser: NightwatchBrowser) {
@ -216,7 +214,6 @@ module.exports = {
.journalLastChildIncludes('"documentation": "param1 from library"')
.journalLastChildIncludes('"documentation": "param2 from library"')
.journalLastChildIncludes('"documentation": "param3 from library"')
.journalLastChildIncludes('Debug the transaction to get more information.')
},
'Should compile and deploy 2 simple contracts, the contract creation component state should be correctly reset for the deployment of the second contract #group4': function (browser: NightwatchBrowser) {

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
'use strict'
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
@ -26,25 +27,30 @@ module.exports = {
.frameParent()
.clickLaunchIcon('filePanel')
.waitForElementVisible({
selector: "//*[@data-id='workspacesSelect' and contains(.,'vyper-lang')]",
selector: "//*[@data-id='workspacesSelect' and contains(.,'snekmate')]",
locateStrategy: 'xpath',
timeout: 60000
})
.currentWorkspaceIs('vyper-lang')
.currentWorkspaceIs('snekmate')
.waitForElementVisible({
selector: "//*[@data-id='treeViewLitreeViewItemexamples' and contains(.,'examples')]",
selector: "//*[@data-id='treeViewLitreeViewItemsrc' and contains(.,'src')]",
locateStrategy: 'xpath',
timeout: 60000
})
.openFile('examples')
.openFile('examples/auctions')
.openFile('examples/auctions/blind_auction.vy')
.openFile('src')
.openFile('src/snekmate')
.openFile('src/snekmate/tokens')
.openFile('src/snekmate/tokens/ERC721.vy')
},
// 'Add vyper file to run tests #group1': function (browser: NightwatchBrowser) {
// browser.addFile('TestBallot.sol', sources[0]['TestBallot.sol'])
// },
'@sources': () => sources,
'Context menu click to compile blind_auction should succeed #group1': function (browser: NightwatchBrowser) {
browser
.click('*[data-id="treeViewLitreeViewItemexamples/auctions/blind_auction.vy"]')
.rightClick('*[data-id="treeViewLitreeViewItemexamples/auctions/blind_auction.vy"]')
.addFileSnekmate('blind_auction.vy', sources[0]['blindAuction'])
.click('*[data-id="treeViewLitreeViewItemblind_auction.vy"]')
.rightClick('*[data-id="treeViewLitreeViewItemblind_auction.vy"]')
.waitForElementPresent('[data-id="contextMenuItemvyper"]')
.click('[data-id="contextMenuItemvyper"]')
.clickLaunchIcon('vyper')
@ -141,6 +147,33 @@ module.exports = {
browser.verifyCallReturnValue(contractAddress, ['0:uint256: 0'])
.perform(() => done())
})
},
'Compile Ownable contract from snekmate #group1': function (browser: NightwatchBrowser) {
let contractAddress
browser
.frameParent()
.clickLaunchIcon('filePanel')
.switchWorkspace('snekmate')
.openFile('src')
.openFile('src/snekmate')
.openFile('src/snekmate/auth')
.openFile('src/snekmate/auth/Ownable.vy')
.rightClick('*[data-id="treeViewLitreeViewItemsrc/snekmate/auth/Ownable.vy"]')
.waitForElementVisible('*[data-id="contextMenuItemvyper"]')
.click('*[data-id="contextMenuItemvyper"]')
.clickLaunchIcon('vyper')
// @ts-ignore
.frame(0)
.click('[data-id="compile"]')
.waitForElementVisible({
selector:'[data-id="compilation-details"]',
timeout: 60000
})
.click('[data-id="compilation-details"]')
.frameParent()
.waitForElementVisible('[data-id="copy-abi"]')
.end()
}
}
@ -176,3 +209,185 @@ def _createPokemon(_name: String[32], _dna: uint256, _HP: uint256):
wins: 0
})
self.totalPokemonCount += 1`
const sources = [{
'blindAuction' : { content: `
# Blind Auction. Adapted to Vyper from [Solidity by Example](https://github.com/ethereum/solidity/blob/develop/docs/solidity-by-example.rst#blind-auction-1)
#pragma version ^0.3.10
struct Bid:
blindedBid: bytes32
deposit: uint256
# Note: because Vyper does not allow for dynamic arrays, we have limited the
# number of bids that can be placed by one address to 128 in this example
MAX_BIDS: constant(int128) = 128
# Event for logging that auction has ended
event AuctionEnded:
highestBidder: address
highestBid: uint256
# Auction parameters
beneficiary: public(address)
biddingEnd: public(uint256)
revealEnd: public(uint256)
# Set to true at the end of auction, disallowing any new bids
ended: public(bool)
# Final auction state
highestBid: public(uint256)
highestBidder: public(address)
# State of the bids
bids: HashMap[address, Bid[128]]
bidCounts: HashMap[address, int128]
# Allowed withdrawals of previous bids
pendingReturns: HashMap[address, uint256]
@external
def __init__(_beneficiary: address, _biddingTime: uint256, _revealTime: uint256):
self.beneficiary = _beneficiary
self.biddingEnd = block.timestamp + _biddingTime
self.revealEnd = self.biddingEnd + _revealTime
# Place a blinded bid with:
#
# _blindedBid = keccak256(concat(
# convert(value, bytes32),
# convert(fake, bytes32),
# secret)
# )
#
# The sent ether is only refunded if the bid is correctly revealed in the
# revealing phase. The bid is valid if the ether sent together with the bid is
# at least "value" and "fake" is not true. Setting "fake" to true and sending
# not the exact amount are ways to hide the real bid but still make the
# required deposit. The same address can place multiple bids.
@external
@payable
def bid(_blindedBid: bytes32):
# Check if bidding period is still open
assert block.timestamp < self.biddingEnd
# Check that payer hasn't already placed maximum number of bids
numBids: int128 = self.bidCounts[msg.sender]
assert numBids < MAX_BIDS
# Add bid to mapping of all bids
self.bids[msg.sender][numBids] = Bid({
blindedBid: _blindedBid,
deposit: msg.value
})
self.bidCounts[msg.sender] += 1
# Returns a boolean value, 'True' if bid placed successfully, 'False' otherwise.
@internal
def placeBid(bidder: address, _value: uint256) -> bool:
# If bid is less than highest bid, bid fails
if (_value <= self.highestBid):
return False
# Refund the previously highest bidder
if (self.highestBidder != empty(address)):
self.pendingReturns[self.highestBidder] += self.highestBid
# Place bid successfully and update auction state
self.highestBid = _value
self.highestBidder = bidder
return True
# Reveal your blinded bids. You will get a refund for all correctly blinded
# invalid bids and for all bids except for the totally highest.
@external
def reveal(_numBids: int128, _values: uint256[128], _fakes: bool[128], _secrets: bytes32[128]):
# Check that bidding period is over
assert block.timestamp > self.biddingEnd
# Check that reveal end has not passed
assert block.timestamp < self.revealEnd
# Check that number of bids being revealed matches log for sender
assert _numBids == self.bidCounts[msg.sender]
# Calculate refund for sender
refund: uint256 = 0
for i in range(MAX_BIDS):
# Note that loop may break sooner than 128 iterations if i >= _numBids
if (i >= _numBids):
break
# Get bid to check
bidToCheck: Bid = (self.bids[msg.sender])[i]
# Check against encoded packet
value: uint256 = _values[i]
fake: bool = _fakes[i]
secret: bytes32 = _secrets[i]
blindedBid: bytes32 = keccak256(concat(
convert(value, bytes32),
convert(fake, bytes32),
secret
))
# Bid was not actually revealed
# Do not refund deposit
assert blindedBid == bidToCheck.blindedBid
# Add deposit to refund if bid was indeed revealed
refund += bidToCheck.deposit
if (not fake and bidToCheck.deposit >= value):
if (self.placeBid(msg.sender, value)):
refund -= value
# Make it impossible for the sender to re-claim the same deposit
zeroBytes32: bytes32 = empty(bytes32)
bidToCheck.blindedBid = zeroBytes32
# Send refund if non-zero
if (refund != 0):
send(msg.sender, refund)
# Withdraw a bid that was overbid.
@external
def withdraw():
# Check that there is an allowed pending return.
pendingAmount: uint256 = self.pendingReturns[msg.sender]
if (pendingAmount > 0):
# If so, set pending returns to zero to prevent recipient from calling
# this function again as part of the receiving call before 'transfer'
# returns (see the remark above about conditions -> effects ->
# interaction).
self.pendingReturns[msg.sender] = 0
# Then send return
send(msg.sender, pendingAmount)
# End the auction and send the highest bid to the beneficiary.
@external
def auctionEnd():
# Check that reveal end has passed
assert block.timestamp > self.revealEnd
# Check that auction has not already been marked as ended
assert not self.ended
# Log auction ending and set flag
log AuctionEnded(self.highestBidder, self.highestBid)
self.ended = True
# Transfer funds to beneficiary
send(self.beneficiary, self.highestBid)
`}
}
]

@ -402,9 +402,15 @@ module.exports = {
'Incorrect content')
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/run_setup.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/run_verification.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/groth16"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/groth16/groth16_trusted_setup.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/groth16/groth16_zkproof.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/plonk"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/plonk/plonk_trusted_setup.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts/plonk/plonk_zkproof.ts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates/groth16_verifier.sol.ejs"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtemplates/plonk_verifier.sol.ejs"]')
.click('*[data-id="treeViewLitreeViewItemtemplates/groth16_verifier.sol.ejs"]')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`contract Groth16Verifier {`) !== -1,
@ -539,8 +545,8 @@ module.exports = {
.currentWorkspaceIs('default_workspace')
},
'Should create a cookbook workspace #group3': function (browser: NightwatchBrowser) {
// This test is disable as it was failing for chrome on CI
'Should create a cookbook workspace #group3': !function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
@ -563,6 +569,17 @@ module.exports = {
.waitForElementVisible('*[data-id="treeViewLitreeViewItemsrc/MULTI_SIG/MultiSigSwapHook.sol"]')
},
'Should add Create2 solidity factory #group4': !function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspaceaddcreate2solidityfactory"]')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`contract Create2FactoryAssembly {`) !== -1,
'current displayed content is not Create2FactoryAssembly')
})
},
tearDown: sauce
}

@ -73,6 +73,8 @@ declare module 'nightwatch' {
waitForElementNotContainsText: (id: string, value: string, timeout: number = 10000) => NightwatchBrowser
hideToolTips: (this: NightwatchBrowser) => NightwatchBrowser
enableClipBoard: () => NightwatchBrowser
addFileSnekmate: (name: string, content: NightwatchContractContent) => NightwatchBrowser
selectFiles: (selelectedElements: any[]) => NightwatchBrowser
}
export interface NightwatchBrowser {

@ -45,27 +45,14 @@
dependencies:
array.prototype.flatmap "^1.2.4"
"@puppeteer/browsers@^1.5.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-1.6.0.tgz#d52413a7039e40a5ef72fb13fb6505fd87ce842e"
integrity sha512-R2ib8j329427jtKB/qlz0MJbwfJE/6I8ocJLiajsRqJ2PPI8DbjiNzC3lQZeISXEcjOBVhbG2RafN8SlHdcT+A==
dependencies:
debug "4.3.4"
extract-zip "2.0.1"
progress "2.0.3"
proxy-agent "6.3.0"
tar-fs "3.0.4"
unbzip2-stream "1.4.3"
yargs "17.7.1"
"@remix-project/remixd@../../dist/libs/remixd":
version "0.6.18"
version "0.6.30"
dependencies:
"@remixproject/plugin" "0.3.33"
"@remixproject/plugin-api" "0.3.33"
"@remixproject/plugin-utils" "0.3.33"
"@remixproject/plugin-ws" "0.3.33"
axios "1.1.2"
axios "1.6.0"
chokidar "^2.1.8"
commander "^9.4.1"
fs-extra "^3.0.1"
@ -111,11 +98,6 @@
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
"@sindresorhus/is@^4.0.0":
version "4.6.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
@ -123,18 +105,6 @@
dependencies:
defer-to-connect "^1.0.1"
"@szmarczak/http-timer@^4.0.5":
version "4.0.6"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807"
integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==
dependencies:
defer-to-connect "^2.0.0"
"@tootallnate/quickjs-emscripten@^0.23.0":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c"
integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==
"@types/bn.js@^5.1.0":
version "5.1.1"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682"
@ -142,28 +112,6 @@
dependencies:
"@types/node" "*"
"@types/cacheable-request@^6.0.1":
version "6.0.3"
resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183"
integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==
dependencies:
"@types/http-cache-semantics" "*"
"@types/keyv" "^3.1.4"
"@types/node" "*"
"@types/responselike" "^1.0.0"
"@types/http-cache-semantics@*":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812"
integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==
"@types/keyv@^3.1.4":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6"
integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==
dependencies:
"@types/node" "*"
"@types/node@*":
version "20.5.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.0.tgz#7fc8636d5f1aaa3b21e6245e97d56b7f56702313"
@ -176,13 +124,6 @@
dependencies:
"@types/node" "*"
"@types/responselike@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==
dependencies:
"@types/node" "*"
"@types/secp256k1@^4.0.1":
version "4.0.3"
resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c"
@ -190,25 +131,11 @@
dependencies:
"@types/node" "*"
"@types/yauzl@^2.9.1":
version "2.10.0"
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599"
integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==
dependencies:
"@types/node" "*"
"@ungap/promise-all-settled@1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
agent-base@^7.0.1, agent-base@^7.0.2, agent-base@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434"
integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==
dependencies:
debug "^4.3.4"
ansi-align@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
@ -345,13 +272,6 @@ assign-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==
ast-types@^0.13.4:
version "0.13.4"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782"
integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==
dependencies:
tslib "^2.0.1"
async-each@^1.0.1:
version "1.0.6"
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.6.tgz#52f1d9403818c179b7561e11a5d1b77eb2160e77"
@ -389,29 +309,15 @@ axe-core@^4.4.3:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.2.tgz#040a7342b20765cb18bb50b628394c21bccc17a0"
integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==
axios@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.1.2.tgz#8b6f6c540abf44ab98d9904e8daf55351ca4a331"
integrity sha512-bznQyETwElsXl2RK7HLLwb5GPpOLlycxHCtrpDR/4RqqBzjARaOTo3jz4IgtntWUYee7Ne4S8UHd92VCuzPaWA==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
axios@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f"
integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==
axios@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102"
integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
b4a@^1.6.4:
version "1.6.4"
resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9"
integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@ -449,11 +355,6 @@ basic-auth@^2.0.1:
dependencies:
safe-buffer "5.1.2"
basic-ftp@^5.0.2:
version "5.0.3"
resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.3.tgz#b14c0fe8111ce001ec913686434fe0c2fb461228"
integrity sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==
binary-extensions@^1.0.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
@ -598,11 +499,6 @@ buffer-alloc@^1.2.0:
buffer-alloc-unsafe "^1.1.0"
buffer-fill "^1.0.0"
buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
buffer-fill@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
@ -613,7 +509,7 @@ buffer-xor@^1.0.3:
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==
buffer@^5.2.1, buffer@^5.5.0:
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
@ -636,11 +532,6 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
cacheable-lookup@^5.0.3:
version "5.0.4"
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
cacheable-request@^6.0.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
@ -654,19 +545,6 @@ cacheable-request@^6.0.0:
normalize-url "^4.1.0"
responselike "^1.0.2"
cacheable-request@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817"
integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==
dependencies:
clone-response "^1.0.2"
get-stream "^5.1.0"
http-cache-semantics "^4.0.0"
keyv "^4.0.0"
lowercase-keys "^2.0.0"
normalize-url "^6.0.1"
responselike "^2.0.0"
call-bind@^1.0.0, call-bind@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
@ -790,15 +668,6 @@ cliui@^7.0.2:
strip-ansi "^6.0.0"
wrap-ansi "^7.0.0"
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.1"
wrap-ansi "^7.0.0"
clone-response@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3"
@ -838,11 +707,6 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
commander@^10.0.0:
version "10.0.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
commander@^9.4.1:
version "9.5.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
@ -901,27 +765,6 @@ create-hmac@^1.1.4, create-hmac@^1.1.7:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"
data-uri-to-buffer@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-5.0.1.tgz#db89a9e279c2ffe74f50637a59a32fb23b3e4d7c"
integrity sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==
debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
debug@4.3.3:
version "4.3.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
@ -943,6 +786,13 @@ debug@^3.2.7:
dependencies:
ms "^2.1.1"
debug@^4.1.1:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
decamelize@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
@ -960,13 +810,6 @@ decompress-response@^3.3.0:
dependencies:
mimic-response "^1.0.0"
decompress-response@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
dependencies:
mimic-response "^3.1.0"
deep-eql@4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.0.1.tgz#2b65bc89491d193780c452edee2144a91bb0a445"
@ -1003,11 +846,6 @@ defer-to-connect@^1.0.1:
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
defer-to-connect@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
define-data-property@^1.0.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3"
@ -1052,15 +890,6 @@ define-property@^2.0.2:
is-descriptor "^1.0.2"
isobject "^3.0.1"
degenerator@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-5.0.1.tgz#9403bf297c6dad9a1ece409b37db27954f91f2f5"
integrity sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==
dependencies:
ast-types "^0.13.4"
escodegen "^2.1.0"
esprima "^4.0.1"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@ -1253,32 +1082,6 @@ escape-string-regexp@4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
escodegen@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17"
integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==
dependencies:
esprima "^4.0.1"
estraverse "^5.2.0"
esutils "^2.0.2"
optionalDependencies:
source-map "~0.6.1"
esprima@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
ethereum-cryptography@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191"
@ -1371,29 +1174,6 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
extract-zip@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
dependencies:
debug "^4.1.1"
get-stream "^5.1.0"
yauzl "^2.10.0"
optionalDependencies:
"@types/yauzl" "^2.9.1"
fast-fifo@^1.1.0, fast-fifo@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.0.tgz#03e381bcbfb29932d7c3afde6e15e83e05ab4d8b"
integrity sha512-IgfweLvEpwyA4WgiQe9Nx6VV2QkML2NkvZnk1oKnIzXgXdWxuhF7zw4DvLTPZJn6PIUneiAXPF24QmoEqHTjyw==
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==
dependencies:
pend "~1.2.0"
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
@ -1469,7 +1249,7 @@ fragment-cache@^0.2.1:
dependencies:
map-cache "^0.2.2"
fs-extra@^10.0.0, fs-extra@^10.1.0:
fs-extra@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
@ -1487,15 +1267,6 @@ fs-extra@^3.0.1:
jsonfile "^3.0.0"
universalify "^0.1.0"
fs-extra@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@ -1586,16 +1357,6 @@ get-symbol-description@^1.0.0:
call-bind "^1.0.2"
get-intrinsic "^1.1.1"
get-uri@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.1.tgz#cff2ba8d456c3513a04b70c45de4dbcca5b1527c"
integrity sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q==
dependencies:
basic-ftp "^5.0.2"
data-uri-to-buffer "^5.0.1"
debug "^4.3.4"
fs-extra "^8.1.0"
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@ -1654,23 +1415,6 @@ gopd@^1.0.1:
dependencies:
get-intrinsic "^1.1.3"
got@^11.8.2:
version "11.8.6"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a"
integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==
dependencies:
"@sindresorhus/is" "^4.0.0"
"@szmarczak/http-timer" "^4.0.5"
"@types/cacheable-request" "^6.0.1"
"@types/responselike" "^1.0.0"
cacheable-lookup "^5.0.3"
cacheable-request "^7.0.2"
decompress-response "^6.0.0"
http2-wrapper "^1.0.0-beta.5.2"
lowercase-keys "^2.0.0"
p-cancelable "^2.0.0"
responselike "^2.0.0"
got@^9.6.0:
version "9.6.0"
resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
@ -1813,14 +1557,6 @@ http-cache-semantics@^4.0.0:
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
http-proxy-agent@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673"
integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==
dependencies:
agent-base "^7.1.0"
debug "^4.3.4"
http-proxy@^1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
@ -1849,22 +1585,6 @@ http-server@^14.1.1:
union "~0.5.0"
url-join "^4.0.1"
http2-wrapper@^1.0.0-beta.5.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
dependencies:
quick-lru "^5.1.1"
resolve-alpn "^1.0.0"
https-proxy-agent@^7.0.0:
version "7.0.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz#0277e28f13a07d45c663633841e20a40aaafe0ab"
integrity sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==
dependencies:
agent-base "^7.0.2"
debug "4"
iconv-lite@0.6.3:
version "0.6.3"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
@ -1909,16 +1629,6 @@ internal-slot@^1.0.5:
has "^1.0.3"
side-channel "^1.0.4"
ip@^1.1.8:
version "1.1.9"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.9.tgz#8dfbcc99a754d07f425310b86a99546b1151e396"
integrity sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
is-accessor-descriptor@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
@ -2110,11 +1820,6 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
is-port-reachable@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/is-port-reachable/-/is-port-reachable-3.1.0.tgz#f6668d3bca9c36b07f737c48a8f875ab0653cd2b"
integrity sha512-vjc0SSRNZ32s9SbZBzGaiP6YVB+xglLShhgZD/FHMZUXBvQWaV9CtzgeVhjccFJrI6RAMV+LX7NYxueW/A8W5A==
is-regex@^1.0.4, is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
@ -2231,11 +1936,6 @@ json-buffer@3.0.0:
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==
json-buffer@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
jsonfile@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
@ -2243,13 +1943,6 @@ jsonfile@^3.0.0:
optionalDependencies:
graceful-fs "^4.1.6"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==
optionalDependencies:
graceful-fs "^4.1.6"
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
@ -2285,13 +1978,6 @@ keyv@^3.0.0:
dependencies:
json-buffer "3.0.0"
keyv@^4.0.0:
version "4.5.3"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.3.tgz#00873d2b046df737963157bd04f294ca818c9c25"
integrity sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==
dependencies:
json-buffer "3.0.1"
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@ -2430,12 +2116,7 @@ lodash.keys@^3.0.0:
lodash.isarguments "^3.0.0"
lodash.isarray "^3.0.0"
lodash.mapvalues@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c"
integrity sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==
lodash.merge@4.6.2, lodash.merge@^4.6.2:
lodash.merge@4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
@ -2477,11 +2158,6 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
lru-cache@^7.14.1:
version "7.18.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89"
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
map-cache@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
@ -2549,11 +2225,6 @@ mimic-response@^1.0.0, mimic-response@^1.0.1:
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
mimic-response@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@ -2590,7 +2261,7 @@ minimist@1.2.6:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.7:
minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
@ -2603,11 +2274,6 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
mkdirp-classic@^0.5.2:
version "0.5.3"
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
mkdirp@^0.5.6:
version "0.5.6"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
@ -2615,11 +2281,6 @@ mkdirp@^0.5.6:
dependencies:
minimist "^1.2.6"
mkdirp@^2.1.3:
version "2.1.6"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19"
integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==
mkpath@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/mkpath/-/mkpath-1.0.0.tgz#ebb3a977e7af1c683ae6fda12b545a6ba6c5853d"
@ -2697,11 +2358,6 @@ nanomatch@^1.2.9:
snapdragon "^0.8.1"
to-regex "^3.0.1"
netmask@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
nightwatch-axe-verbose@2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/nightwatch-axe-verbose/-/nightwatch-axe-verbose-2.0.3.tgz#719f0a1b53d611fa2b4872ee5730f5c0ad2c0cec"
@ -2775,11 +2431,6 @@ normalize-url@^4.1.0:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
normalize-url@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
object-copy@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
@ -2879,11 +2530,6 @@ p-cancelable@^1.0.0:
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
p-cancelable@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==
p-limit@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
@ -2898,29 +2544,6 @@ p-locate@^5.0.0:
dependencies:
p-limit "^3.0.2"
pac-proxy-agent@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-7.0.0.tgz#db42120c64292685dafaf2bd921e223c56bfb13b"
integrity sha512-t4tRAMx0uphnZrio0S0Jw9zg3oDbz1zVhQ/Vy18FjLfP1XOLNUEjaVxYCYRI6NS+BsMBXKIzV6cTLOkO9AtywA==
dependencies:
"@tootallnate/quickjs-emscripten" "^0.23.0"
agent-base "^7.0.2"
debug "^4.3.4"
get-uri "^6.0.1"
http-proxy-agent "^7.0.0"
https-proxy-agent "^7.0.0"
pac-resolver "^7.0.0"
socks-proxy-agent "^8.0.1"
pac-resolver@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-7.0.0.tgz#79376f1ca26baf245b96b34c339d79bff25e900c"
integrity sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==
dependencies:
degenerator "^5.0.0"
ip "^1.1.8"
netmask "^2.0.2"
package-json@^6.3.0:
version "6.5.0"
resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0"
@ -2956,11 +2579,6 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
pathval@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
@ -2977,11 +2595,6 @@ pbkdf2@^3.0.17:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
picomatch@^2.0.4, picomatch@^2.2.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
@ -3011,11 +2624,6 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
progress@2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
proper-lockfile@^4.1.1:
version "4.1.2"
resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f"
@ -3025,20 +2633,6 @@ proper-lockfile@^4.1.1:
retry "^0.12.0"
signal-exit "^3.0.2"
proxy-agent@6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.3.0.tgz#72f7bb20eb06049db79f7f86c49342c34f9ba08d"
integrity sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==
dependencies:
agent-base "^7.0.2"
debug "^4.3.4"
http-proxy-agent "^7.0.0"
https-proxy-agent "^7.0.0"
lru-cache "^7.14.1"
pac-proxy-agent "^7.0.0"
proxy-from-env "^1.1.0"
socks-proxy-agent "^8.0.1"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
@ -3059,16 +2653,6 @@ qs@^6.4.0:
dependencies:
side-channel "^1.0.4"
queue-tick@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142"
integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==
quick-lru@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@ -3189,11 +2773,6 @@ requires-port@^1.0.0:
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
resolve-alpn@^1.0.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==
resolve-url@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
@ -3206,13 +2785,6 @@ responselike@^1.0.2:
dependencies:
lowercase-keys "^1.0.0"
responselike@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc"
integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==
dependencies:
lowercase-keys "^2.0.0"
restore-cursor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
@ -3323,28 +2895,6 @@ secure-compare@3.0.1:
resolved "https://registry.yarnpkg.com/secure-compare/-/secure-compare-3.0.1.tgz#f1a0329b308b221fae37b9974f3d578d0ca999e3"
integrity sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==
selenium-standalone@^9.0.3:
version "9.0.3"
resolved "https://registry.yarnpkg.com/selenium-standalone/-/selenium-standalone-9.0.3.tgz#2e484c5412d28e60f4b8837305b2f573f28e8147"
integrity sha512-uv2Cx+VVwVSxBoUdA+fjiyXPNyP9fFZf3sl8hokz+KetNNMXZw6s+fxkUNvmZKL0jdvAI/fnHf+xjMCo/0NiKQ==
dependencies:
"@puppeteer/browsers" "^1.5.0"
axios "^1.4.0"
commander "^10.0.0"
cross-spawn "^7.0.3"
debug "^4.3.1"
fs-extra "^10.0.0"
got "^11.8.2"
is-port-reachable "^3.0.0"
lodash.mapvalues "^4.6.0"
lodash.merge "^4.6.2"
minimist "^1.2.5"
mkdirp "^2.1.3"
progress "2.0.3"
tar-stream "3.1.6"
which "^2.0.2"
yauzl "^2.10.0"
selenium-webdriver@4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.3.1.tgz#5e9c6c4adee65e57776b5bd4c07c59b65b8f056d"
@ -3405,18 +2955,6 @@ sha.js@^2.4.0, sha.js@^2.4.8:
inherits "^2.0.1"
safe-buffer "^5.0.1"
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
dependencies:
shebang-regex "^3.0.0"
shebang-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
@ -3431,11 +2969,6 @@ signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
smart-buffer@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae"
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@ -3466,23 +2999,6 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
socks-proxy-agent@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz#ffc5859a66dac89b0c4dab90253b96705f3e7120"
integrity sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ==
dependencies:
agent-base "^7.0.1"
debug "^4.3.4"
socks "^2.7.1"
socks@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55"
integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==
dependencies:
ip "^2.0.0"
smart-buffer "^4.2.0"
solidity-ast@^0.4.51:
version "0.4.52"
resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.52.tgz#9f1a9abc7e5ba28bbf91146ecd07aec7e70f3c85"
@ -3511,11 +3027,6 @@ source-map@^0.5.6:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
split-string@^3.0.1, split-string@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
@ -3538,15 +3049,7 @@ static-extend@^0.1.1:
define-property "^0.2.5"
object-copy "^0.1.0"
streamx@^2.15.0:
version "2.15.1"
resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.1.tgz#396ad286d8bc3eeef8f5cea3f029e81237c024c6"
integrity sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==
dependencies:
fast-fifo "^1.1.0"
queue-tick "^1.0.1"
string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -3654,29 +3157,6 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
tar-fs@3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.4.tgz#a21dc60a2d5d9f55e0089ccd78124f1d3771dbbf"
integrity sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==
dependencies:
mkdirp-classic "^0.5.2"
pump "^3.0.0"
tar-stream "^3.1.5"
tar-stream@3.1.6, tar-stream@^3.1.5:
version "3.1.6"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.6.tgz#6520607b55a06f4a2e2e04db360ba7d338cc5bab"
integrity sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==
dependencies:
b4a "^1.6.4"
fast-fifo "^1.2.0"
streamx "^2.15.0"
through@^2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
tmp@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
@ -3731,11 +3211,6 @@ tslib@2.0.1:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e"
integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==
tslib@^2.0.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410"
integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==
type-detect@4.0.8, type-detect@^4.0.0:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
@ -3800,14 +3275,6 @@ unbox-primitive@^1.0.2:
has-symbols "^1.0.3"
which-boxed-primitive "^1.0.2"
unbzip2-stream@1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7"
integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==
dependencies:
buffer "^5.2.1"
through "^2.3.8"
union-value@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
@ -3916,7 +3383,7 @@ which-typed-array@^1.1.10, which-typed-array@^1.1.11:
gopd "^1.0.1"
has-tostringtag "^1.0.0"
which@2.0.2, which@^2.0.1, which@^2.0.2:
which@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
@ -3979,11 +3446,6 @@ yargs-parser@^20.2.2:
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs-unparser@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb"
@ -4007,27 +3469,6 @@ yargs@16.2.0:
y18n "^5.0.5"
yargs-parser "^20.2.2"
yargs@17.7.1:
version "17.7.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967"
integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.1.1"
yauzl@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
dependencies:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"

@ -17,7 +17,7 @@ sleep 5
node apps/remix-ide/ci/splice_tests.js $2 $3
TESTFILES=$(node apps/remix-ide/ci/splice_tests.js $2 $3 | circleci tests split --split-by=timings)
for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/${TESTFILE}.js --env=$1 || npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/${TESTFILE}.js --env=$1 || TEST_EXITCODE=1
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch-${1}.js dist/apps/remix-ide-e2e/src/tests/${TESTFILE}.js --env=$1 || npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch-${1}.js dist/apps/remix-ide-e2e/src/tests/${TESTFILE}.js --env=$1 || TEST_EXITCODE=1
done
echo "$TEST_EXITCODE"

@ -15,7 +15,7 @@ sleep 5
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep $1 | sort | circleci tests split )
for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $TESTFILE --env=chrome || TEST_EXITCODE=1
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch-chrome.js $TESTFILE --env=chrome || TEST_EXITCODE=1
done
echo "$TEST_EXITCODE"

@ -23,7 +23,7 @@ yarn run serve:production &
sleep 5
for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $TESTFILE --env=$1 || TEST_EXITCODE=1
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch-${1}.js $TESTFILE --env=$1 || TEST_EXITCODE=1
done
echo "$TEST_EXITCODE"

@ -37,17 +37,12 @@ import {HardhatProvider} from './app/providers/hardhat-provider'
import {GanacheProvider} from './app/providers/ganache-provider'
import {FoundryProvider} from './app/providers/foundry-provider'
import {ExternalHttpProvider} from './app/providers/external-http-provider'
import {InjectedProviderDefault} from './app/providers/injected-provider-default'
import {InjectedProviderTrustWallet} from './app/providers/injected-provider-trustwallet'
import {Injected0ptimismProvider} from './app/providers/injected-optimism-provider'
import {InjectedArbitrumOneProvider} from './app/providers/injected-arbitrum-one-provider'
import {InjectedEphemeryTestnetProvider} from './app/providers/injected-ephemery-testnet-provider'
import {InjectedSKALEChaosTestnetProvider} from './app/providers/injected-skale-chaos-testnet-provider'
import { FileDecorator } from './app/plugins/file-decorator'
import { CodeFormat } from './app/plugins/code-format'
import { SolidityUmlGen } from './app/plugins/solidity-umlgen'
import { CompilationDetailsPlugin } from './app/plugins/compile-details'
import { VyperCompilationDetailsPlugin } from './app/plugins/vyper-compilation-details'
import { RemixGuidePlugin } from './app/plugins/remixGuide'
import { ContractFlattener } from './app/plugins/contractFlattener'
import { TemplatesPlugin } from './app/plugins/remix-templates'
import { fsPlugin } from './app/plugins/electron/fsPlugin'
@ -229,6 +224,10 @@ class AppComponent {
// ----------------- Compilation Details ----------------------------
const compilationDetails = new CompilationDetailsPlugin(appManager)
const vyperCompilationDetails = new VyperCompilationDetailsPlugin(appManager)
// ----------------- Remix Guide ----------------------------
const remixGuide = new RemixGuidePlugin(appManager)
// ----------------- ContractFlattener ----------------------------
const contractFlattener = new ContractFlattener()
@ -269,12 +268,6 @@ class AppComponent {
const ganacheProvider = new GanacheProvider(blockchain)
const foundryProvider = new FoundryProvider(blockchain)
const externalHttpProvider = new ExternalHttpProvider(blockchain)
const trustWalletInjectedProvider = new InjectedProviderTrustWallet()
const defaultInjectedProvider = new InjectedProviderDefault()
const injected0ptimismProvider = new Injected0ptimismProvider()
const injectedArbitrumOneProvider = new InjectedArbitrumOneProvider()
const injectedEphemeryTestnetProvider = new InjectedEphemeryTestnetProvider()
const injectedSKALEChaosTestnetProvider = new InjectedSKALEChaosTestnetProvider()
// ----------------- convert offset to line/column service -----------
const offsetToLineColumnConverter = new OffsetToLineColumnConverter()
Registry.getInstance().put({
@ -348,17 +341,12 @@ class AppComponent {
ganacheProvider,
foundryProvider,
externalHttpProvider,
defaultInjectedProvider,
trustWalletInjectedProvider,
injected0ptimismProvider,
injectedArbitrumOneProvider,
injectedEphemeryTestnetProvider,
injectedSKALEChaosTestnetProvider,
this.walkthroughService,
search,
solidityumlgen,
compilationDetails,
vyperCompilationDetails,
// remixGuide,
contractFlattener,
solidityScript,
templates,
@ -418,7 +406,8 @@ class AppComponent {
filePanel,
Registry.getInstance().get('compilersartefacts').api,
networkModule,
Registry.getInstance().get('fileproviders/browser').api
Registry.getInstance().get('fileproviders/browser').api,
this.engine
)
const analysis = new AnalysisTab()
const debug = new DebuggerTab()
@ -525,6 +514,7 @@ class AppComponent {
await this.appManager.activatePlugin(['filePanel'])
// Set workspace after initial activation
this.appManager.on('editor', 'editorMounted', () => {
if (Array.isArray(this.workspace)) {

@ -0,0 +1,244 @@
import React from 'react'
import { ViewPlugin } from '@remixproject/engine-web'
import { PluginViewWrapper } from '@remix-ui/helper'
import { RemixAppManager } from '../../remixAppManager'
import { RemixUIGridView } from '@remix-ui/remix-ui-grid-view'
import { RemixUIGridSection } from '@remix-ui/remix-ui-grid-section'
import { RemixUIGridCell } from '@remix-ui/remix-ui-grid-cell'
import { ThemeKeys, ThemeObject } from '@microlink/react-json-view'
//@ts-ignore
const _paq = (window._paq = window._paq || [])
const profile = {
name: 'remixGuide',
displayName: 'Remix Guide',
description: 'Learn remix with videos',
location: 'mainPanel',
methods: ['showDetails'],
events: []
}
export class RemixGuidePlugin extends ViewPlugin {
dispatch: React.Dispatch<any> = () => { }
appManager: RemixAppManager
element: HTMLDivElement
payload: any
themeStyle: any
theme: ThemeKeys | ThemeObject
constructor(appManager: RemixAppManager) {
super(profile)
this.appManager = appManager
this.element = document.createElement('div')
this.element.setAttribute('id', 'remixGuideEl')
}
async onActivation() {
this.handleThemeChange()
await this.call('tabs', 'focus', 'remixGuide')
this.renderComponent()
_paq.push(['trackEvent', 'plugin', 'activated', 'remixGuide'])
}
onDeactivation(): void {
}
async showDetails(sentPayload: any) {
const contractName = Object.entries(sentPayload).find(([key, value]) => key)
await this.call('tabs', 'focus', 'remixGuide')
this.profile.displayName = `${contractName[0]}`
this.payload = sentPayload
const active = await this.call('theme', 'currentTheme')
this.renderComponent()
}
private handleThemeChange() {
this.on('theme', 'themeChanged', (theme: any) => {
this.renderComponent()
})
}
setDispatch(dispatch: React.Dispatch<any>): void {
this.dispatch = dispatch
this.renderComponent()
}
render() {
return (
<div className="bg-dark" id="remixGuide">
<PluginViewWrapper plugin={this} />
</div>
)
}
renderComponent() {
this.dispatch({
...this,
...this.payload,
themeStyle: this.themeStyle,
theme: this.theme
})
}
updateComponent(state: any) {
return (
<RemixUIGridView
plugin={this}
styleList={""}
logo='/assets/img/YouTubeLogo.webp'
enableFilter={true}
showUntagged={true}
showPin={true}
tagList={[
['beginner', 'danger'],
['advanced', 'warning'],
['AI', 'success'],
['plugins', 'secondary'],
['solidity', 'primary'],
['vyper', 'info'],
['L2', 'danger']
]}
title='Remix Guide'
description="Streamlined access to categorized video tutorials for mastering Remix IDE. From fundamentals to advanced techniques, level up your development skills with ease."
//themeStyle={state.themeStyle}
>
<RemixUIGridSection
plugin={this}
title='Basics'
hScrollable= {true}
>
<RemixUIGridCell
plugin={this}
title="first item"
tagList={['L2', 'AI']}
logo='/assets/img/soliditySurvey2023.webp'
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="next"
pinned={true}
tagList={['L2', 'plugins']}
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell> <RemixUIGridCell
plugin={this}
title="something"
pinned={false}
tagList={['solidity', 'plugins']}
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="1"
tagList={['solidity']}
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell> <RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="Something very very long"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell> <RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
</RemixUIGridSection>
<RemixUIGridSection
plugin={this}
title='Basics not scrollable'
hScrollable= {false}
>
<RemixUIGridCell
plugin={this}
title="first item"
logo='/assets/img/soliditySurvey2023.webp'
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="next"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell> <RemixUIGridCell
plugin={this}
title="something"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell> <RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell> <RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
<RemixUIGridCell
plugin={this}
title="1"
>
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img>
</RemixUIGridCell>
</RemixUIGridSection>
</RemixUIGridView>
)
}
}

@ -15,7 +15,7 @@ const profile = {
name: 'solcoder',
displayName: 'solcoder',
description: 'solcoder',
methods: ['code_generation', 'code_completion', "solidity_answer", "code_explaining"],
methods: ['code_generation', 'code_completion', "solidity_answer", "code_explaining", "code_insertion"],
events: [],
maintainedBy: 'Remix',
}
@ -32,7 +32,6 @@ export class SolCoder extends Plugin {
async code_generation(prompt): Promise<any> {
this.emit("aiInfering")
this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: 'Code Generation: Waiting for Solcoder answer...'})
let result
try {
result = await(
@ -45,7 +44,6 @@ export class SolCoder extends Plugin {
body: JSON.stringify({"data":[prompt, "code_completion", "", false,1000,0.9,0.92,50]}),
})
).json()
console.log(result)
if ("error" in result){
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: result.error })
return result
@ -62,7 +60,6 @@ export class SolCoder extends Plugin {
async solidity_answer(prompt): Promise<any> {
this.emit("aiInfering")
this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: 'Waiting for Solcoder answer...'})
let result
try {
result = await(
@ -89,10 +86,9 @@ export class SolCoder extends Plugin {
}
async code_explaining(prompt): Promise<any> {
async code_explaining(prompt, context:string=""): Promise<any> {
this.emit("aiInfering")
this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: 'Explain Code: Waiting for Solcoder answer...'})
let result
try {
result = await(
@ -102,7 +98,7 @@ export class SolCoder extends Plugin {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({"data":[prompt, "code_explaining", false,2000,0.9,0.8,50]}),
body: JSON.stringify({"data":[prompt, "code_explaining", false,2000,0.9,0.8,50, context]}),
})
).json()
if (result) {
@ -151,7 +147,6 @@ export class SolCoder extends Plugin {
).json()
if ("error" in result){
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: result.error })
return result
}
return result.data
@ -164,5 +159,42 @@ export class SolCoder extends Plugin {
}
}
async code_insertion(msg_pfx, msg_sfx): Promise<any> {
this.emit("aiInfering")
let result
try {
result = await(
await fetch(this.completion_url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({"data":[
msg_pfx, // Text before current cursor line
"code_insertion",
msg_sfx, // Text after current cursor line
1024,
0.5,
0.92,
50
] }),
})
).json()
if ("error" in result){
return result
}
return result.data
} catch (e) {
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: `Unable to get a response ${e.message}` })
return
} finally {
this.emit("aiInferingDone")
}
}
}

@ -119,7 +119,7 @@ export abstract class AbstractProvider extends Plugin implements IProvider {
}
this.call('notification', 'alert', modalContent)
}
await this.call('udapp', 'setEnvironmentMode', {context: 'vm-paris'})
await this.call('udapp', 'setEnvironmentMode', {context: 'vm-cancun'})
return
}

@ -1,14 +1,15 @@
import {InjectedProviderDefaultBase} from './injected-provider-default'
import Web3 from 'web3'
import {InjectedProviderDefault} from './injected-provider-default'
export class InjectedCustomProvider extends InjectedProviderDefaultBase {
export class InjectedCustomProvider extends InjectedProviderDefault {
chainName: string
chainId: string
rpcUrls: Array<string>
nativeCurrency: Record<string, any>
blockExplorerUrls: Array<string>
constructor(profile: any, chainName: string, chainId: string, rpcUrls: Array<string>, nativeCurrency?: Record<string, any>, blockExplorerUrls?: Array<string>) {
super(profile)
constructor(provider: any, chainName: string, chainId: string, rpcUrls: Array<string>, nativeCurrency?: Record<string, any>, blockExplorerUrls?: Array<string>) {
super(provider, chainName)
this.chainName = chainName
this.chainId = chainId
this.rpcUrls = rpcUrls
@ -17,14 +18,17 @@ export class InjectedCustomProvider extends InjectedProviderDefaultBase {
}
async init() {
if (!this.chainId && this.rpcUrls.length > 0) {
const chainId = await new Web3(this.rpcUrls[0]).eth.getChainId()
this.chainId = `0x${chainId.toString(16)}`
}
await super.init()
if (this.chainName && this.rpcUrls && this.rpcUrls.length > 0) await addCustomNetwork(this.chainName, this.chainId, this.rpcUrls, this.nativeCurrency, this.blockExplorerUrls)
else throw new Error('Cannot add the custom network to main injected provider')
await setCustomNetwork(this.chainName, this.chainId, this.rpcUrls, this.nativeCurrency, this.blockExplorerUrls)
return {}
}
}
export const addCustomNetwork = async (chainName: string, chainId: string, rpcUrls: Array<string>, nativeCurrency?: Record<string, any>, blockExplorerUrls?: Array<string>) => {
export const setCustomNetwork = async (chainName: string, chainId: string, rpcUrls: Array<string>, nativeCurrency?: Record<string, any>, blockExplorerUrls?: Array<string>) => {
try {
await (window as any).ethereum.request({
method: 'wallet_switchEthereumChain',
@ -34,6 +38,7 @@ export const addCustomNetwork = async (chainName: string, chainId: string, rpcUr
// This error code indicates that the chain has not been added to MetaMask.
if (switchError.code === 4902) {
try {
if (chainName && rpcUrls && rpcUrls.length > 0) {
const paramsObj: Record<string, any> = {
chainId: chainId,
chainName: chainName,
@ -50,6 +55,7 @@ export const addCustomNetwork = async (chainName: string, chainId: string, rpcUr
method: 'wallet_switchEthereumChain',
params: [{chainId: chainId}]
})
}
} catch (addError) {
// handle "add" error
}

@ -25,7 +25,7 @@ export class InjectedProviderDefaultBase extends InjectedProvider {
}
const profile = {
name: 'injected',
name: 'injected', // the name will be overwritten in the constructor.
displayName: 'Injected Provider',
kind: 'provider',
description: 'injected Provider',
@ -34,7 +34,13 @@ const profile = {
}
export class InjectedProviderDefault extends InjectedProviderDefaultBase {
constructor() {
super(profile)
provider: any
constructor(provider: any, name: string) {
super({ ...profile, ...{ name, displayName: name } })
this.provider = provider
}
getInjectedProvider() {
return this.provider
}
}

@ -8,6 +8,7 @@ import zhJson from './locales/zh'
import esJson from './locales/es'
import frJson from './locales/fr'
import itJson from './locales/it'
import ruJson from './locales/ru'
const _paq = window._paq = window._paq || []
const locales = [
@ -15,6 +16,7 @@ const locales = [
{ code: 'en', name: 'English', localeName: 'English', messages: enJson },
{ code: 'fr', name: 'French', localeName: 'Français', messages: frJson },
{ code: 'it', name: 'Italian', localeName: 'Italiano', messages: itJson },
{ code: 'ru', name: 'Russian', localeName: 'Русский', messages: ruJson },
{ code: 'es', name: 'Spanish', localeName: 'Español', messages: esJson }
]

@ -36,6 +36,8 @@
"filePanel.addscriptetherscan": "Add Etherscan scripts",
"filePanel.workspace.addscriptsindri": "Adds scripts for interacting with Sindri, a zk proof generation remote service",
"filePanel.addscriptsindri": "Add Sindri ZK scripts",
"filePanel.workspace.addcreate2solidityfactory": "A contract which allows you to deploy a contract using CREATE2.",
"filePanel.addcreate2solidityfactory": "Add Create2 Solidity factory",
"filePanel.workspace.addscriptdeployer": "Adds scripts which can be used to deploy contracts",
"filePanel.addscriptdeployer": "Add contract deployer scripts",
"filePanel.workspace.slitherghaction": "Adds a preset yml file to run slither analysis on github actions CI",

@ -4,9 +4,9 @@
"remixUiTabs.tooltipText3": "Select .sol or .yul file to compile or a .ts or .js file and run it",
"remixUiTabs.tooltipText4": "Select .sol file to use AI tools [BETA]",
"remixUiTabs.tooltipText5": "Explain the contract(s) in current file [BETA]",
"remixUiTabs.tooltipText6": "Enable AI Copilot [BETA]",
"remixUiTabs.tooltipText7": "Disable AI Copilot [BETA]",
"remixUiTabs.tooltipText8": "AI Documentation [BETA]",
"remixUiTabs.tooltipText6": "Enable Remix AI Copilot [BETA]",
"remixUiTabs.tooltipText7": "Disable Remix AI Copilot [BETA]",
"remixUiTabs.tooltipText8": "Remix AI Tools Documentation [BETA]",
"remixUiTabs.zoomOut": "Zoom out",
"remixUiTabs.zoomIn": "Zoom in"
}

@ -3,7 +3,9 @@
"udapp._comment_gasPrice.tsx": "libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx",
"udapp.gasLimit": "Gas limit",
"udapp.tooltipText4": "The default gas limit is 3M. Adjust as needed.",
"udapp.gasLimitAuto": "Estimated Gas",
"udapp.gasLimitManual": "Custom",
"udapp.tooltipText4": "Enter custom Gas Limit.",
"udapp._comment_value.tsx": "libs/remix-ui/run-tab/src/lib/components/value.tsx",
"udapp.value": "Value",
@ -70,12 +72,12 @@
"udapp.deployAndRunNoInstanceText": "Currently you have no unpinned contracts to interact with.",
"udapp.tooltipText6": "Autogenerated generic user interfaces for interaction with deployed/unpinned contracts",
"udapp.savedContracts": "Pinned Contracts",
"udapp.pinnedContracts": "Pinned Contracts",
"udapp.tooltipTextPinnedContracts": "List of pinned contracts for selected workspace & network",
"udapp.NoSavedInstanceText": "No pinned contracts found for selected workspace & network",
"udapp.tooltipTextDelete": "Delete pinned contract",
"udapp.NoPinnedInstanceText": "No pinned contracts found for selected workspace & network",
"udapp.tooltipTextDelete": "Delete immediately",
"udapp.tooltipTextUnpin": "Unpin contract",
"udapp.savedOn": "Pinned at",
"udapp.pinnedAt": "Pinned at",
"udapp.filePath": "File path",
"udapp._comment_recorderCardUI.tsx": "libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx",

@ -0,0 +1,15 @@
{
"circuit.compiler": "Компилятор",
"circuit.autoCompile": "Автокомпиляция",
"circuit.hideWarnings": "Скрыть предупреждения",
"circuit.advancedConfigurations": "Расширенные настройки",
"circuit.compilerConfiguration": "Настройки компилятора",
"circuit.prime": "Изначально",
"circuit.useConfigurationFile": "Использовать файл настроек",
"circuit.compile": "Скомпилировать",
"circuit.noFileSelected": "нет выбранных файлов",
"circuit.generateR1cs": "Сгенерировать R1CS",
"circuit.computeWitness": "Вычислить Witness",
"circuit.signalInput": "Сигнал ввода",
"circuit.compute": "Вычислить"
}

@ -0,0 +1,26 @@
{
"debugger.displayName": "Отладчик",
"debugger.debuggerConfiguration": "Настройки отладчика",
"debugger.stopDebugging": "Завершить отладку",
"debugger.provideTxNumber": "Пожалуйста, укажите действительный хэш транзакции",
"debugger.startDebugging": "Начать отладку",
"debugger.placeholder": "Хэш транзакции, должен начинаться с 0x",
"debugger.debugLocaNodeLabel": "Принудительное использование локального узла",
"debugger.useGeneratedSources": "Использовать сгенерированные источники",
"debugger.debugWithGeneratedSources": "Когда флажок установлен, то отладчик проверит скомпилированный файл .yul, если он существует.",
"debugger.introduction": "При отладке с хэшем транзакции, если контракт проверен, Remix попытается получить исходный код из Sourcify или Etherscan. Укажите API ключ Etherscan в настройках Remix. Поддерживаемые сети смотрите в",
"debugger.forceToUseCurrentLocalNode": "Заставить отладчик использовать текущий локальный узел",
"debugger.sourceLocationStatus1": "Поиск контрольной точки. Это может занять некоторое время...",
"debugger.sourceLocationStatus2": "Местоположение источника недоступно ни в Sourcify ни в Etherscan. Пожалуйста, убедитесь, что ключ api Etherscan указан в настройках.",
"debugger.sourcifyDocs": "Документации Sourcify",
"debugger.noDataAvailable": "Данные отсутствуют",
"debugger.loadMore": "Загрузить еще",
"debugger.copy": "Копировать",
"debugger.stepOverBack": "Шаг назад",
"debugger.stepBack": "Назад",
"debugger.stepInto": "Шаг в",
"debugger.stepOverForward": "Шаг вперед",
"debugger.jumpPreviousBreakpoint": "Перейти к предыдущей контрольной точке",
"debugger.jumpOut": "Выпрыгнуть",
"debugger.jumpNextBreakpoint": "Перейти к предыдущей контрольной точке"
}

@ -0,0 +1,134 @@
{
"filePanel.displayName": "Файловый менеджер",
"filePanel.workspace": "ПРОЕКТЫ",
"filePanel.create": "Создать",
"filePanel.clone": "Клонировать",
"filePanel.download": "Скачать",
"filePanel.backup": "Резервная копия",
"filePanel.restore": "Восстановить",
"filePanel.workspace.create": "Создать проект",
"filePanel.workspace.rename": "Переименовать проект",
"filePanel.workspace.save_workspace": "Сохранить проект",
"filePanel.workspace.delete": "Удалить проект",
"filePanel.workspace.deleteConfirm": "Вы уверены, что хотите удалить текущий проект?",
"filePanel.workspace.download": "Скачать проект",
"filePanel.workspace.downloadConfirm": "Текущий проект будет загружен в виде zip-файла. Вы хотите продолжить?",
"filePanel.workspace.deleteAll": "Удалить все проекты",
"filePanel.workspace.deleteAllConfirm1": "Вы уверены, что хотите удалить все ваши проекты?",
"filePanel.workspace.deleteAllConfirm2": "Удаленные проекты не могут быть восстановлены каким-либо образом.",
"filePanel.workspace.name": "Название проекта",
"filePanel.workspace.chooseTemplate": "Выбрать шаблон",
"filePanel.workspace.backup": "Резервное копирование всех проектов",
"filePanel.workspace.restore": "Восстановить проекты из резервной копии",
"filePanel.workspace.clone": "Клонировать репозиторий",
"filePanel.workspace.cloneMessage": "Пожалуйста, укажите действительный url git репозитория.",
"filePanel.workspace.enterGitUrl": "Введите url git репозитория",
"filePanel.workspace.switch": "Переключиться на проект",
"filePanel.workspace.solghaction": "Добавляет предустановленный yml файл для запуска модульных тестов Solidity в действиях github CI.",
"filePanel.solghaction": "Рабочий процесс тестирования Solidity",
"filePanel.workspace.tssoltestghaction": "Добавляет предустановленный yml файл для запуска mocha и chai тестов на прочность CI действий на github",
"filePanel.tssoltestghaction": "Рабочий процесс Mocha Chai Test",
"filePanel.workspace.addscriptetherscan": "Добавляет скрипты, которые могут использоваться для взаимодействия с Etherscan API",
"filePanel.addscriptetherscan": "Добавить скрипты Etherscan",
"filePanel.workspace.addscriptdeployer": "Добавляет скрипты, которые могут использоваться для развертывания контрактов",
"filePanel.addscriptdeployer": "Добавить скрипты развертывания контракта",
"filePanel.workspace.slitherghaction": "Добавляет предустановленный yml файл для запуска модульных тестов Solidity в действиях github CI",
"filePanel.slitherghaction": "Рабочий процесс Slither",
"filePanel.workspace.helperscripts": "Добавляет удобные скрипты в директорию 'scripts'",
"filePanel.helperscripts": "Web3 скрипты",
"filePanel.newFile": "Новый файл",
"filePanel.newFolder": "Новая папка",
"filePanel.rename": "Переименовать",
"filePanel.delete": "Удалить",
"filePanel.deleteAll": "Удалить всё",
"filePanel.run": "Запустить",
"filePanel.pushChangesToGist": "Отправить изменения в Gist",
"filePanel.publishFolderToGist": "Опубликовать папку в Gist",
"filePanel.publishFileToGist": "Опубликовать файл в Gist",
"filePanel.copy": "Копировать",
"filePanel.copyFileName": "Копировать название",
"filePanel.copyFilePath": "Копировать путь",
"filePanel.contractflattener": "Сведение",
"filePanel.nahmii-compiler": "Компиляция Nahmii",
"filePanel.solidityumlgen": "Сгенерировать UML",
"filePanel.doc-gen": "Генерировать документы",
"filePanel.solidity": "Скомпилировать",
"filePanel.paste": "Вставить",
"filePanel.compile": "Скомпилировать",
"filePanel.compileForNahmii": "Компиляция для Nahmii",
"filePanel.createNewFile": "Создать новый файл",
"filePanel.createNewFolder": "Создать новую папку",
"filePanel.publishToGist": "Опубликовать все файлы в GitHub Gist",
"filePanel.uploadFile": "Загрузить файлы",
"filePanel.uploadFolder": "Загрузка папки",
"filePanel.updateGist": "Обновить текущий обозреватель [gist]",
"filePanel.viewAllBranches": "Просмотреть все ветки",
"filePanel.createBranch": "Создать ветку",
"filePanel.switchBranches": "Переключить ветку",
"filePanel.checkoutGitBranch": "Проверьте Git ветку",
"filePanel.findOrCreateABranch": "Найти или создать ветку.",
"filePanel.initGitRepositoryLabel": "Инициализировать рабочую область как новый git репозиторий",
"filePanel.initGitRepositoryWarning": "Чтобы использовать функции Git, добавьте имя пользователя и адрес электронной почты в раздел Github на Панели настроек.",
"filePanel.workspaceName": "Название рабочей области",
"filePanel.customizeTemplate": "Настроить шаблон",
"filePanel.features": "Особенности",
"filePanel.upgradeability": "Улучшение",
"filePanel.ok": "OK",
"filePanel.yes": "Да",
"filePanel.cancel": "Отменить",
"filePanel.createNewWorkspace": "создать новую рабочую область",
"filePanel.connectToLocalhost": "подключиться к локальному хосту",
"filePanel.copiedToClipboard": "Скопировано в буфер обмена {path}",
"filePanel.downloadFailed": "Ошибка загрузки",
"filePanel.downloadFailedMsg": "Непредвиденная ошибка при загрузке: {error}",
"filePanel.close": "Закрыть",
"filePanel.copyFileFailed": "Ошибка копирования файла",
"filePanel.copyFileFailedMsg": "Непредвиденная ошибка при копировании файла: {src}",
"filePanel.copyFolderFailed": "Ошибка копирования папки",
"filePanel.copyFolderFailedMsg": "Непредвиденная ошибка при копировании папки: {src}",
"filePanel.runScriptFailed": "Не удалось запустить скрипт",
"filePanel.createPublicGist": "Создать публичный Gist",
"filePanel.createPublicGistMsg1": "Вы уверены, что хотите отправить изменения в удалённый файл gist на github.com?",
"filePanel.createPublicGistMsg2": "Вы уверены, что хотите анонимно опубликовать все ваши файлы в папке {path} как публичный файл на github.com?",
"filePanel.createPublicGistMsg3": "Вы уверены, что хотите анонимно опубликовать все ваши файлы в папке {path} как публичный файл на github.com?",
"filePanel.createPublicGistMsg4": "Вы уверены, что хотите анонимно опубликовать все ваши файлы в папке {name} как публичный файл на github.com?",
"filePanel.deleteMsg": "Вы уверены, что хотите удалить?",
"filePanel.theseItems": "эти элементы",
"filePanel.thisItem": "этот элемент",
"filePanel.deleteItems": "Удалить элементы",
"filePanel.deleteItem": "Удалить элемент",
"filePanel.globalToast": "Невозможно записать/изменить файловую систему в режиме только для чтения.",
"filePanel.basic": "Основной",
"filePanel.blank": "Пустой",
"filePanel.multiSigWallet": "Кошелек с мультиподписью",
"filePanel.mintable": "Чеканный",
"filePanel.burnable": "Ожигаемый",
"filePanel.pausable": "Пауза",
"filePanel.semaphore": "Семафор",
"filePanel.hashchecker": "Хэш-чекер",
"filePanel.rln": "Обнулитель ограничения частоты запросов",
"filePanel.breakthroughLabsUniswapv4Hooks": "Breakthrough-Labs Hooks",
"filePanel.uniswapV4Periphery": "V4 периферия",
"filePanel.uniswapV4HookBookMultiSigSwapHook": "HookBook MultiSigSwapHook",
"filePanel.transparent": "Прозрачный",
"filePanel.initGitRepoTitle": "Установите флажок для активизации рабочей области как нового git репозитория",
"filePanel.switchToBranchTitle1": "Проверить новую ветку из удалённой ветки",
"filePanel.switchToBranchTitle2": "Выдать в локальную ветку",
"filePanel.readOnly": "только для чтения",
"filePanel.renameFileFailed": "Не удалось переименовать файл",
"filePanel.renameFileFailedMsg": "Непредвиденная ошибка при переименовании: {error}",
"filePanel.fileCreationFailed": "Ошибка создания файла",
"filePanel.folderCreationFailed": "Ошибка создания папки",
"filePanel.validationError": "Ошибка проверки",
"filePanel.validationErrorMsg": "Нельзя использовать специальные символы",
"filePanel.reservedKeyword": "Зарезервированное ключевое слово",
"filePanel.reservedKeywordMsg": "Имя файла содержит зарезервированные ключевые слова Remix \".{content}\"",
"filePanel.moveFile": "Перемещение файлов",
"filePanel.moveFileMsg1": "Вы уверены, что хотите переместить {src} в {dest}?",
"filePanel.movingFileFailed": "Не удалось переместить файл",
"filePanel.movingFileFailedMsg": "Непредвиденная ошибка при перемещении файла: {src}",
"filePanel.movingFolderFailed": "Не удалось переместить папку",
"filePanel.movingFolderFailedMsg": "Непредвиденная ошибка при перемещении папки: {src}",
"filePanel.workspaceActions": "Действия в рабочей области",
"filePanel.saveCodeSample": "Эта рабочая область примера кода не будет сохранена. Нажмите здесь, чтобы сохранить."
}

@ -0,0 +1,69 @@
{
"home.scamAlert": "Предупреждение о мошенничестве",
"home.scamAlertText": "Единственный URL, который использует Remix, - это remix.ethereum.org",
"home.scamAlertText2": "Остерегайтесь видеороликов, рекламирующих \"ботов-передовиков ликвидности\"",
"home.scamAlertText3": "Дополнительные советы по технике безопасности",
"home.learnMore": "Узнать больше",
"home.here": "здесь",
"home.featured": "Рекомендуемые",
"home.jumpIntoWeb3": "Перейти в WEB3",
"home.jumpIntoWeb3More": "Подробнее",
"home.jumpIntoWeb3Text": "Remix IDE является частью проекта Remix, широкий выбор инструментов которого, может быть использован для всего путешествия по разработке контракта пользователями любого уровня знаний. Узнайте больше на сайте проекта Remix.",
"home.remixYouTube": "СМОТРИМ И УЧИМСЯ",
"home.remixYouTubeText1": "Видео советы от команды Remix",
"home.remixYouTubeMore": "Смотреть",
"home.remixYouTubeText2": "У Remix растущая библиотека видео, содержащая множество советов по использованию инструмента. Проверьте их и подпишитесь, чтобы получить наши последние обновления.",
"home.betaTesting": "БЕТА-ТЕСТИРОВАНИЕ",
"home.betaTestingText1": "Наше сообщество поддерживает нас.",
"home.betaTestingText2": "Помогите нам запустить бета-тестирование прямо сейчас и ознакомьтесь с новыми функциями",
"home.betaTestingMore": "Зарегистрироваться",
"home.featuredPlugins": "Рекомендуемые плагины",
"home.solidityPluginDesc": "Компиляция, тестирование и анализ смарт-контрактов.",
"home.cookbookDesc": "Найти смарт-контракты, solidity библиотеки и обнаружить протоколы.",
"home.codeAnalyizerPluginDesc": "Анализируйте ваш код с помощью Remix, Solhint и Slither.",
"home.starkNetPluginDesc": "Компиляция и развертывание контрактов с Cairo, родным языком StarkNet.",
"home.solhintPluginDesc": "Solhint — проект с открытым исходным кодом для линейки кода Solidity.",
"home.sourcifyPluginDesc": "Контракт Solidity и сервис проверки метаданных.",
"home.unitTestPluginDesc": "Напишите и запустите модульные тесты для ваших контрактов в Solidity.",
"home.dgitPluginDesc": "Добавить контроль за исходным кодом в ваши проекты.",
"home.oneClickDappDesc": "Быстрое создание смарт-контрактных интерфейсов",
"home.getStarted": "Приступить к работе",
"home.projectTemplates": "Шаблоны проектов",
"home.blankTemplateDesc": "Создать пустую рабочую область.",
"home.remixDefaultTemplateDesc": "Создать рабочую область с файлами примеров.",
"home.ozerc20TemplateDesc": "Создайте ERC20 токен, импортируя библиотеку OpenZeppelin.",
"home.ozerc721TemplateDesc": "Создайте NFT токен, импортируя библиотеку OpenZeppelin.",
"home.ozerc1155TemplateDesc": "Создайте ERC1155 токен, импортируя библиотеку OpenZeppelin.",
"home.gnosisSafeMultisigTemplateDesc": "Создайте кошельки с мульти-подписью с использованием этого шаблона.",
"home.zeroxErc20TemplateDesc": "Создайте токен ERC20, импортируя контракт с 0xProject.",
"home.learn": "Обучение",
"home.learnEth1": "Основы Remix",
"home.learnEth1Desc": "Введение в интерфейс Remix-а и основные операции.",
"home.learnEth2": "Введение в Solidity",
"home.learnEth2Desc": "Интерактивное изучение концепции Solidity для начинающих.",
"home.remixAdvanced": "Развертывание с Библиотеками",
"home.remixAdvancedDesc": "Научитесь развертывать с библиотеками в Remix",
"home.remixYoutubePlaylist": "Плейлист Remix на Youtube",
"home.remixTwitterProfile": "Remix Twitter Профиль",
"home.remixLinkedinProfile": "Remix Linkedin профиль",
"home.remixMediumPosts": "Remix Medium публикации",
"home.joinUsOnDiscord": "Присоединяйтесь к нам в Discord",
"home.nativeIDE": "Родная IDE для разработки WEB3.",
"home.website": "Веб-сайт",
"home.documentation": "Документация",
"home.remixPlugin": "Remix плагин",
"home.remixDesktop": "Remix Desktop",
"home.searchDocumentation": "Поиск документации",
"home.files": "Файлы",
"home.newFile": "Новый файл",
"home.startCoding": "Начать кодирование",
"home.startCodingPlayground": "Откройте площадку для прототипирования и простого обучения",
"home.openFile": "Открыть файл",
"home.openFileTooltip": "Откройте файл из вашей файловой системы",
"home.accessFileSystem": "Доступ к файловой системе",
"home.loadFrom": "Загрузить из",
"home.resources": "Источники",
"home.connectToLocalhost": "Подключиться к локальному хосту",
"home.seeAllTutorials": "Посмотреть все уроки",
"home.maintainedByRemix": "Поддерживается Remix"
}

@ -0,0 +1,17 @@
import enJson from '../en'
function readAndCombineJsonFiles() {
const dataContext = require.context('./', true, /\.json$/)
let combinedData = {}
dataContext.keys().forEach((key) => {
const jsonData = dataContext(key)
combinedData = {...combinedData, ...jsonData}
})
return combinedData
}
// There may have some un-translated content. Always fill in the gaps with EN JSON.
// No need for a defaultMessage prop when render a FormattedMessage component.
export default Object.assign({}, enJson, readAndCombineJsonFiles())

@ -0,0 +1,10 @@
{
"panel.author": "Автор",
"panel.maintainedBy": "Поддерживается",
"panel.documentation": "Документация",
"panel.description": "Описание",
"panel.maintainedByRemix": "Поддерживается Remix",
"panel.pluginInfo": "Информация о плагине",
"panel.linkToDoc": "Ссылка на документацию",
"panel.makeAnissue": "Создать задачу"
}

@ -0,0 +1,13 @@
{
"permissionHandler.allPermissionsReset": "Все разрешения были сброшены.",
"permissionHandler.rememberText": "изменено и",
"permissionHandler.permissionHandlerMessage": "\"{from}\" {rememberText} хочет получить доступ к \"{method}\" из \"{to}\"`",
"permissionHandler.description": "Описание",
"permissionHandler.noDescriptionProvided": "Описание отсутствует",
"permissionHandler.makeSureYouTrustThisPlugin": "Убедитесь, что Вы доверяете этому плагину перед обработкой этого вызова. Если Вы запомните выбор для этого вызова, то значение будет сохранено только для текущей сессии.",
"permissionHandler.rememberThisChoice": "Запомнить этот выбор",
"permissionHandler.resetAllPermissions": "Сбросить все разрешения",
"permissionHandler.permissionNeededFor": "Для {to} необходимо разрешение",
"permissionHandler.accept": "Принять",
"permissionHandler.decline": "Отклонить"
}

@ -0,0 +1,43 @@
{
"pluginManager.displayName": "Менеджер плагинов",
"pluginManager.activate": "Активировать",
"pluginManager.deactivate": "Деактивировать",
"pluginManager.activeModules": "Активные модули",
"pluginManager.inactiveModules": "Неактивные модули",
"pluginManager.connectLocal": "Подключиться к локальному плагину",
"pluginManager.localForm.title": "Локальный плагин",
"pluginManager.localForm.pluginName": "Название плагина",
"pluginManager.localForm.shouldBeCamelCase": "Должно быть в camelCase",
"pluginManager.localForm.displayName": "Отображаемое название",
"pluginManager.localForm.nameInTheHeader": "Название в заголовке",
"pluginManager.localForm.required": "требуется",
"pluginManager.localForm.commaSeparatedMethod": "список методов через запятую",
"pluginManager.localForm.commaSeparatedPlugin": "список названий плагинов через запятую",
"pluginManager.localForm.pluginsItCanActivate": "Плагины, которые могут быть активированы",
"pluginManager.localForm.typeOfConnection": "Тип соединения",
"pluginManager.localForm.locationInRemix": "Расположение в Remix",
"pluginManager.localForm.sidePanel": "Боковая панель",
"pluginManager.localForm.mainPanel": "Главная панель",
"pluginManager.localForm.none": "Пусто",
"pluginManager.localForm.methods": "Методы",
"pluginManager.localForm.pluginNames": "Имя плагина",
"pluginManager.localForm.ok": "OK",
"pluginManager.localForm.cancel": "Отменить",
"pluginManager.Permissions": "Разрешения",
"pluginManager.permissions": "разрешения",
"pluginManager.pluginManagerPermissions": "Разрешения менеджера плагинов",
"pluginManager.currentPermissionSettings": "Текущие настройки разрешений",
"pluginManager.noPermissionRequestedYet": "Пока нет запрошенных разрешений.",
"pluginManager.allow": "Разрешить",
"pluginManager.toCall": "чтобы вызвать",
"pluginManager.ok": "OK",
"pluginManager.cancel": "Отменить",
"pluginManager.maintainedByRemix": "Поддерживается Remix",
"pluginManager.linkToDoc": "Ссылка на документацию",
"pluginManager.versionAlpha": "Альфа-версия",
"pluginManager.versionBeta": "Бета-версия",
"pluginManager.deactivatePlugin": "Отключить {pluginName}",
"pluginManager.activatePlugin": "Включить {pluginName}",
"pluginManager.search": "Поиск",
"pluginManager.managePluginsPermissions": "Управление разрешениями плагинов"
}

@ -0,0 +1,3 @@
{
"remixApp.scrollToSeeAllTabs": "Прокрутите, чтобы увидеть все вкладки"
}

@ -0,0 +1,7 @@
{
"remixUiTabs.tooltipText1": "Запуск скрипта (CTRL + SHIFT + S)",
"remixUiTabs.tooltipText2": "Компилировать CTRL + S",
"remixUiTabs.tooltipText3": "Выберите файл c расширением .sol или .yul для компиляции или файл .ts или .js для запуска",
"remixUiTabs.zoomOut": "Уменьшить",
"remixUiTabs.zoomIn": "Увеличить"
}

@ -0,0 +1,24 @@
{
"search.displayName": "Поиск в файлах",
"search.replace": "Заменить",
"search.replaceAll": "Заменить все",
"search.placeholder1": "Искать ( Введите для поиска )",
"search.placeholder2": "Включить ie *.sol ( Введите для включения)",
"search.placeholder3": "Исключить ie .git/**/* ( Введите для исключения )",
"search.matchCase": "Учитывать регистр",
"search.matchWholeWord": "Только слово целиком",
"search.useRegularExpression": "Использовать регулярные выражения",
"search.replaceWithoutConfirmation": "заменить без подтверждения",
"search.filesToInclude": "Файлы для включения",
"search.filesToExclude": "Файлы для исключения",
"search.toggleReplace": "Переключить замену",
"search.replaceInFiles": "заменить в файлах",
"search.stop": "Стоп",
"search.undoChanges": "Отменить изменения {path}",
"search.confirmreplaceMsg": "Вы уверены, что вы хотите заменить \"{find}\" на \"{replace}\" в {filename}?",
"search.yes": "Да",
"search.no": "Нет",
"search.loading": "Загрузка",
"search.text1": "Показать {count} результаты в {fileCount} файлах",
"search.text2": "Слишком много результатов для отображения...{br} Пожалуйста, сузьте поиск."
}

@ -0,0 +1,44 @@
{
"settings.displayName": "Настройки",
"settings.reset": "Сбросить до настроек по умолчанию",
"settings.general": "Общие настройки",
"settings.generateContractMetadataText": "Генерирует метаданные договора. Генерирует JSON-файл в папке с договором. Позволяет указать адреса библиотек, от которых зависит контракт. Если ничего не указано, то Remix развертывает библиотеки автоматически.",
"settings.ethereunVMText": "Всегда использовать виртуальную машину Remix при загрузке",
"settings.wordWrapText": "Обводка слов в редакторе",
"settings.useAutoCompleteText": "Включение завершения кода в редакторе.",
"settings.useShowGasInEditorText": "Отобразить в редакторе расчеты газа.",
"settings.displayErrorsText": "Отображать ошибки в редакторе при вводе текста.",
"settings.matomoAnalytics": "Включение Matomo Analytics. Мы не собираем личную информацию (ПД). Эта информация используется для улучшения UX и пользовательского интерфейса сайта. Узнайте больше ",
"settings.enablePersonalModeText": " Включение персонального режима для провайдера web3. Транзакция, отправленная через Web 3, будет использовать web 3.personal API.",
"settings.warnText": "Убедитесь, что конечная точка открыта перед включением. Этот режим позволяет пользователю предоставить парольную фразу в интерфейсе Remix без необходимости разблокировать аккаунт. Несмотря на то, что это очень удобно, вы должны полностью доверять бэкэнду, к которому вы подключены (Geth, Parity, ...). Remix никогда не будет сохраняться парольная фраза",
"settings.gitAccessTokenTitle": "Учетные данные Github",
"settings.gitAccessTokenText": "Токен доступа используется для публикации Gist и получения содержимого GitHub. Возможно, вам потребуется ввести имя пользователя/электронную почту.",
"settings.gitAccessTokenText2": "Перейдите на страницу токенов github (ссылка ниже), создайте новый токен и сохраните его в Remix. Убедитесь, что этот токен имеет только право 'create gist'",
"settings.etherscanTokenTitle": "Токен доступа EtherScan",
"settings.etherscanAccessTokenText": "Управляйте ключом api, используемым для взаимодействия с Etherscan.",
"settings.etherscanAccessTokenText2": "Перейдите на страницу api ключей Etherscan (ссылка ниже), чтобы создать новый api ключ и сохраните его в Remix.",
"settings.save": "Сохранить",
"settings.remove": "Удалить",
"settings.themes": "Темы",
"settings.locales": "Язык",
"settings.swarm": "Настройки Swarm",
"settings.ipfs": "Настройки IPFS",
"settings.token": "ТОКЕН",
"settings.copy": "Копировать",
"settings.deleteEtherscanToken": "Удалить Etherscan токен",
"settings.username": "ИМЯ ПОЛЬЗОВАТЕЛЯ",
"settings.email": "Электронная почта",
"settings.deleteGithubCredentials": "Удалить учетные данные Github",
"settings.privateBeeAddress": "ПРИВАТНЫЙ BEE АДРЕС",
"settings.postageStampID": "ID почтового штампа",
"settings.host": "Хост",
"settings.protocol": "Протокол",
"settings.port": "ПОРТ",
"settings.projectID": "ID ПРОЕКТА",
"settings.projectSecret": "СЕКРЕТ ПРОЕКТА",
"settings.analyticsInRemix": "Аналитика в Remix IDE",
"settings.copilot": "Solidity второй пилот - Альфа",
"settings.copilot.activate": "Загрузка и активация копилота",
"settings.copilot.max_new_tokens": "Максимальное количество слов для генерации",
"settings.copilot.temperature": "Температура"
}

@ -0,0 +1,81 @@
{
"solidity.displayName": "Компилятор Solidity",
"solidity._comment_compiler-container.tsx": "libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx",
"solidity.compiler": "Компилятор",
"solidity.addACustomCompiler": "Добавить пользовательский компилятор",
"solidity.addACustomCompilerWithURL": "Добавить пользовательский компилятор со ссылкой URL",
"solidity.includeNightlyBuilds": "Включить ночные сборки",
"solidity.autoCompile": "Автокомпиляция",
"solidity.hideWarnings": "Скрыть предупреждения",
"solidity.enableHardhat": "Включить Hardhat компиляцию",
"solidity.learnHardhat": "Узнайте, как использовать аппаратную компиляцию",
"solidity.enableTruffle": "Включить компиляцию Truffle",
"solidity.learnTruffle": "Узнайте, как использовать Truffle компиляцию",
"solidity.advancedConfigurations": "Расширенные конфигурации",
"solidity.compilerConfiguration": "Конфигурация Компилятора",
"solidity.compilationDetails": "Подробности компиляции",
"solidity.language": "Язык",
"solidity.evmVersion": "Версия EVM",
"solidity.enableOptimization": "Включить оптимизацию",
"solidity.useConfigurationFile": "Использовать файл настроек",
"solidity.change": "Изменить",
"solidity.compile": "Скомпилировать",
"solidity.noFileSelected": "файл не выбран",
"solidity.compileAndRunScript": "Компиляция и запуск скрипта",
"solidity.newConfigFileTitle": "Новый файл конфигурации",
"solidity.newConfigFileMessage": "Файл \"{configFilePathInput}\" который вы ввели не существует. Хотите создать новый?",
"solidity.create": "Создать",
"solidity.ok": "OK",
"solidity.cancel": "Отменить",
"solidity.noFileSelected1": "Нет выбранных файлов.",
"solidity.toCompile": "скомпилировать",
"solidity.noConfigFileSelected": "Не выбран файл конфигурации",
"solidity.copyNatSpecTag": "Нажмите, чтобы скопировать пользовательский тег NatSpec",
"solidity.inputTitle1": "Если файл, который вы ввели, не существует, вы сможете создать его на следующем шаге.",
"solidity.inputTitle2": "Расчетное количество раз, когда каждый опцион развернутого кода будет выполняться в течение всего срока действия контракта.",
"solidity.tooltipText1": "Выберите сценарий для выполнения сразу после компиляции, добавив тег `dev-run-script` natspec как в:",
"solidity.tooltipText2": "Нажмите на значок \"i\", чтобы узнать больше",
"solidity.tooltipText3": "для компиляции и выполнения скрипта",
"solidity.tooltipText4": "Нажмите, чтобы открыть файл конфигурации",
"solidity.tooltipText5": "Не удается загрузить список версий компилятора. Возможно, он заблокирован блокировщиком рекламы. Пожалуйста, попробуйте отключить любой из них с этой страницы и перезагрузить. Ошибка: ",
"solidity.tooltipText6": "Спецификация языка доступна от Компилятора >= v0.5.7",
"solidity.toastMessage": "Обновление версии компилятора, чтобы соответствовать текущему файлу контракта pragma т.е. {version}",
"solidity.compileIconAttribute": "компилятор загружается, пожалуйста, подождите несколько минут.",
"solidity.compilerLicense": "Лицензия Компилятора",
"solidity.compilerLicenseMsg1": "Загрузка компилятора. Лицензия будет отображаться после загрузки компилятора",
"solidity.compilerLicenseMsg2": "Не удалось получить лицензию для выбранной версии компилятора",
"solidity.compilerLicenseMsg3": "Лицензия недоступна",
"solidity.seeCompilerLicense": "Посмотреть лицензию компилятора",
"solidity._comment_contract-selection.tsx": "libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx",
"solidity.publishOn": "Опубликовано на",
"solidity.flatten": "Сглаживание контракта до генерации UML.",
"solidity.generateUML": "Создать UML диаграмму вашего контракта.",
"solidity.flattenLabel": "Сведение",
"solidity.generateUMLLabel": "Генерировать UML диаграмму",
"solidity.copy": "Копировать",
"solidity.copyABI": "Копировать ABI в буфер обмена",
"solidity.copyBytecode": "Копировать Bytecode в буфер обмена",
"solidity.unableToDisplay": "Не удается отобразить",
"solidity.download": "Скачать",
"solidity.compileDetails": "Скачать информацию о компиляции (формат JSON)",
"solidity.close": "Закрыть",
"solidity.contract": "Контракт",
"solidity.displayContractDetails": "Показать детали контракта",
"solidity.noContractCompiled": "Контракт еще не компилирован",
"solidity.Assembly": "Коды сборки, описывающие контракт, включая соответствующий исходный код Solidity",
"solidity.Opcodes": "Коды сборки с описанием контракта",
"solidity.name": "Название скомпилированного контракта",
"solidity.metadata": "Содержит всю информацию, относящуюся к компиляции",
"solidity.bytecode": "Байт-код, выполняемый при создании контракта",
"solidity.abi": "ABI: описание всех функций (входные и выходные параметры, область применения, ...)",
"solidity.web3Deploy": "Скопируйте или вставьте этот код в любую консоль JavaScript/Web3 для развертывания этого контракта",
"solidity.metadataHash": "Хэш представляющий всю метаинформацию",
"solidity.functionHashes": "Список объявленных функций и их соответствующий хэш",
"solidity.gasEstimates": "Оценка газа для каждого вызова функции",
"solidity.Runtime Bytecode": "Байт-код хранит состояние и выполняется во время обычного вызова контракта",
"solidity.storageLayout": "См. документацию по схеме хранилища.",
"solidity.devdoc": "Документация для разработчиков (natspec)",
"solidity.userdoc": "Документация пользователя (natspec)",
"solidity.compilerInput": "Ввод в компилятор Solidity",
"solidity.swarmLocation": "Url - адрес Swarm в котором можно найти всю информацию о метаданных (контракт должен быть опубликован первым)"
}

@ -0,0 +1,41 @@
{
"solidityUnitTesting.displayName": "Модульное тестирование Solidity",
"solidityUnitTesting.testDirectory": "Тестовая директория",
"solidityUnitTesting.testYourSmartContract": "Проверьте ваш смарт - контракт в Solidity.",
"solidityUnitTesting.selectDirectory": "Выберите директорию для загрузки и создания тестовых файлов.",
"solidityUnitTesting.uiPathInputTooltip": "Нажмите 'Enter', чтобы изменить путь к тестовым файлами.",
"solidityUnitTesting.uiPathInputButtonTooltip": "Создать тестовую папку",
"solidityUnitTesting.create": "Создать",
"solidityUnitTesting.generateTestsButtonTooltip": "Создать пример тестового файла",
"solidityUnitTesting.generate": "Генерировать",
"solidityUnitTesting.generateTestsLinkTooltip": "Ознакомьтесь с документацией.",
"solidityUnitTesting.howToUse": "Как использовать...",
"solidityUnitTesting.runButtonTitle1": "Начать тесты",
"solidityUnitTesting.runButtonTitle2": "Пожалуйста, выберите версию компилятора Solidity выше чем 0.4.12.",
"solidityUnitTesting.runButtonTitle3": "Не выбран Solidity файл",
"solidityUnitTesting.runButtonTitle4": "Solidity плагин должен быть активирован",
"solidityUnitTesting.runButtonTitle5": "Тестовый файл не выбран",
"solidityUnitTesting.stopButtonLabel1": "Стоп",
"solidityUnitTesting.stopButtonLabel2": "Останавливается",
"solidityUnitTesting.run": "Запустить",
"solidityUnitTesting.runTestsTabStopActionTooltip": "Остановить запуск тестов",
"solidityUnitTesting.selectAll": "Выбрать все",
"solidityUnitTesting.testTabTestsExecutionStopped": "Выполнение теста остановлено",
"solidityUnitTesting.testTabTestsExecutionStoppedError": "Выполнение теста остановлено из-за ошибки(ошибок) в вашем тестовом файле",
"solidityUnitTesting.progress": "Прогресс: {readyTestsNumber} завершён (из {runningTestsNumber})",
"solidityUnitTesting.resultFor": "Результат для",
"solidityUnitTesting.passed": "Успешно",
"solidityUnitTesting.failed": "Сбой",
"solidityUnitTesting.timeTaken": "Затраченное время",
"solidityUnitTesting.errorMessage": "Сообщение об ошибке",
"solidityUnitTesting.assertion": "Утверждение",
"solidityUnitTesting.expectedValueShouldBe": "Ожидаемое значение должно быть",
"solidityUnitTesting.receivedValue": "Полученные значения",
"solidityUnitTesting.skippingTheRemainingTests": "Пропуск оставшихся тестов функции.",
"solidityUnitTesting.toasterMsg": "Папка успешно создана",
"solidityUnitTesting.tooltipText1": "Не удалось выполнить тест по крайней мере одного контракта",
"solidityUnitTesting.tooltipText2": "Все контрактные тесты пройдены",
"solidityUnitTesting.tooltipText3": "Начать отладку",
"solidityUnitTesting.fail": "НЕПРОЙДЕН",
"solidityUnitTesting.pass": "ПРОЙДЕН"
}

@ -0,0 +1,43 @@
{
"terminal.listen": "прослушивание всех транзакций",
"terminal.listenTitle": "Если флажок установлен, то Remix будет прослушивать все транзакции, добытые в текущей среде, а не только транзакции, созданные вами",
"terminal.search": "Поиск по хэшу или адресу транзакции",
"terminal.used": "используется",
"terminal.debug": "Отладка",
"terminal.welcomeText1": "Добро пожаловать в",
"terminal.welcomeText2": "Ваши файлы хранятся в",
"terminal.welcomeText3": "Вы можете использовать этот терминал для",
"terminal.welcomeText4": "Проверьте детали транзакций и начните отладку",
"terminal.welcomeText5": "Выполнение скриптов JavaScript",
"terminal.welcomeText6": "Введите сценарий непосредственно в интерфейсе командной строки",
"terminal.welcomeText7": "Выберите файл Javascript в проводнике файлов, а затем запустите \"remix.execute()\" или \"remix.exeCurrent()\" в интерфейсе командной строки",
"terminal.welcomeText8": "Щелкните правой кнопкой мыши на файл JavaScript в проводнике и затем нажмите `Выполнить`",
"terminal.welcomeText9": "Доступны следующие библиотеки",
"terminal.welcomeText10": "Введите имя библиотеки, чтобы увидеть доступные команды",
"terminal.text1": "Этот тип команды устарел и больше не функционирует. Пожалуйста, запустите remix.help(), чтобы получить список доступных команд.",
"terminal.hideTerminal": "Скрыть терминал",
"terminal.showTerminal": "Показать терминал",
"terminal.clearConsole": "Очистить консоль",
"terminal.pendingTransactions": "Ожидающие транзакции",
"terminal.toasterMsg1": "нет контента для выполнения",
"terminal.toasterMsg2": "не найден поставщик пути {fileName}",
"terminal.vmMode": "Режим VM",
"terminal.vmModeMsg": "Не удается отладить этот вызов. Отладка вызовов возможна только в режиме Remix VM.",
"terminal.ok": "Ok",
"terminal.cancel": "Отменить",
"terminal.callWarning": "(Применяется только в случае вызова контракта)",
"terminal.msg1": "Транзакция добыта, но выполнение не удалось",
"terminal.msg2": "Успешное выполнение транзакций",
"terminal.msg3": "Статус недоступен в данный момент",
"terminal.status": "статус",
"terminal.transactionHash": "хеш транзакции",
"terminal.blockHash": "хеш блока",
"terminal.blockNumber": "номер блока",
"terminal.contractAddress": "адрес контракта",
"terminal.transactionCost": "стоимость транзакции",
"terminal.executionCost": "стоимость исполнения",
"terminal.input": "ввод",
"terminal.decodedInput": "декодированный ввод",
"terminal.decodedOutput": "декодированный вывод",
"terminal.logs": "журналы"
}

@ -0,0 +1,139 @@
{
"udapp.displayName": "Развертывание и запуск транзакций",
"udapp._comment_gasPrice.tsx": "libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx",
"udapp.gasLimit": "Лимит газа",
"udapp.tooltipText4": "Стандартный газовой лимит составляет 3М. Регулировка по мере необходимости.",
"udapp._comment_value.tsx": "libs/remix-ui/run-tab/src/lib/components/value.tsx",
"udapp.value": "Значение",
"udapp.tooltipText5": "Введите сумму и выберите ее единицу",
"udapp._comment_contractDropdownUI.tsx": "libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx",
"udapp.contract": "Контракт",
"udapp.compiledBy": "скомпилировано {compilerName}",
"udapp.warningEvmVersion": "Пожалуйста, убедитесь, что выбранная сеть совместима с данной Evm версией: {evmVersion}. В противном случае развёртывание закончится неудачно.",
"udapp.infoSyncCompiledContractTooltip": "Нажмите здесь, чтобы импортировать контакты, скомпилированные из внешней платформы.\nЭто действие включается, когда Remix подключён к внешнему фреймворку (hardhat, truffle, foundry) через remixd",
"udapp.remixIpfsUdappTooltip": "Публикация исходного кода и метаданных IPFS облегчает верификацию исходного кода с помощью Sourcify и значительно ускоряет принятие контракта (аудит, отладка, вызов и т.д...)",
"udapp.deploy": "Развернуть",
"udapp.publishTo": "Опубликовать в",
"udapp.atAddress": "At Address",
"udapp.atAddressOptionsTitle1": "адрес контракта",
"udapp.atAddressOptionsTitle2": "Для взаимодействия с развёрнутым контрактом, необходимо выбрать в редакторе файл .abi или скомпилированный файл .sol (с той же конфигурацией компилятора)",
"udapp.atAddressOptionsTitle3": "Компилируйте *.sol файл или выберите файл *.abi.",
"udapp.atAddressOptionsTitle4": "Для взаимодействия с развёрнутым контрактом, либо введите его адрес и скомпилируйте исходный файл *.sol (с такими же настройками компилятора) или выберите его .abi файл в редакторе.",
"udapp.contractOptionsTitle1": "Пожалуйста, скомпилируйте *.sol файл для развертывания или доступа к контракту",
"udapp.contractOptionsTitle2": "Выберите скомпилированный контракт для развертывания или используйте по адресу.",
"udapp.contractOptionsTitle3": "Выберите и скомпилируйте *.sol файл для развертывания или доступа к контракту.",
"udapp.contractOptionsTitle4": "При наличии скомпилированного файла .sol, выберите контракт для развертывания или использования с параметром \"At Address\".",
"udapp.checkSumWarning": "Похоже вы не используете адрес с контрольной суммой. Адрес с контрольной суммой это адрес который состоит из заглавных букв, как указано в {a}. Контрольные адреса предназначены для предотвращения отправки пользователями транзакций по ошибочному адресу.",
"udapp.isOverSizePromptEip170": "Инициализация создания контракта возвращает данные длиной более 24576 байт. Развёртывание скорее всего завершится неудачей, если текущая сеть активировала eip 170. Дополнительная информация: {a}",
"udapp.isOverSizePromptEip3860": "Код инициализации контракта превышает допустимый максимальный размер кода 49152 байта. Развёртывание скорее всего не будет выполнено, если текущая сеть активировала eip 3860. Дополнительная информация: {a}",
"udapp.thisContractMayBeAbstract": "Этот контракт может быть абстрактным, он может не полностью применять методы абстрактного родительского объекта или он может неправильно вызывать унаследованный конструктор контракта.",
"udapp.noCompiledContracts": "Компилированных контрактов нет",
"udapp.addressOfContract": "Адрес контракта",
"udapp.loadContractFromAddress": "Загрузить контракт из адреса",
"udapp.ok": "OK",
"udapp.alert": "Предупреждение",
"udapp.proceed": "Продолжить",
"udapp.cancel": "Отменить",
"udapp.abiFileSelected": "Выбран файл ABI",
"udapp.evmVersion": "версия EVM",
"udapp.addressNotValid": "Адрес не действителен",
"udapp._comment_account.tsx": "libs/remix-ui/run-tab/src/lib/components/account.tsx",
"udapp.account": "Аккаунт",
"udapp.signAMessage": "Подписать сообщение",
"udapp.enterAMessageToSign": "Введите сообщение для подписания",
"udapp.hash": "хэш",
"udapp.signature": "подпись",
"udapp.injectedTitle": "К сожалению, невозможно создать учетную запись с помощью внедрённого провайдера. Пожалуйста, создайте аккаунт непосредственно у вашего провайдера (т.е. Metamask или другого такого же типа).",
"udapp.createNewAccount": "Создать новый аккаунт",
"udapp.web3Title": "Создание учетной записи возможно только в Личном режиме. Пожалуйста, перейдите в Настройки, чтобы включить ее.",
"udapp.defaultTitle": "К сожалению, невозможно создать учетную запись с помощью внешнего кошелька ({selectExEnv}).",
"udapp.text1": "Пожалуйста, укажите пароль для создания учетной записи",
"udapp.tooltipText1": "Список учётных записей пуст, пожалуйста, убедитесь, что текущий провайдер правильно подключен к remix",
"udapp.modalTitle1": "Парольная фраза для подписания сообщения",
"udapp.modalMessage1": "Введите ваш пароль для этой учётной записи чтобы подписания сообщения",
"udapp.copyAccount": "Копировать аккаунт в буфер обмена",
"udapp.signMsgUsingAccount": "Подписать сообщение, используя эту учетную запись",
"udapp._comment_environment.tsx": "libs/remix-ui/run-tab/src/lib/components/environment.tsx",
"udapp.environment": "Среда",
"udapp.environmentDocs": "Нажмите для получения документации о Среде",
"udapp.tooltipText2": "Откройте chainlist.org и получите данные подключения к цепочке, с которой вы хотите взаимодействовать.",
"udapp.tooltipText3": "Нажмите, чтобы открыть мост для преобразования L1 mainnet ETH в выбранную сетевую валюту.",
"udapp._comment_instanceContainerUI.tsx": "libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx",
"udapp.deployedContracts": "Развернутые контракты",
"udapp.deployAndRunClearInstances": "Очистить список экземпляров и сбросить рекордер",
"udapp.deployAndRunNoInstanceText": "В настоящее время у вас нет экземпляров контракта для взаимодействия.",
"udapp.tooltipText6": "Автоматически создаваемые пользовательские интерфейсы для взаимодействия с развернутыми контрактами",
"udapp._comment_recorderCardUI.tsx": "libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx",
"udapp.transactionsRecorded": "Транзакции записаны",
"udapp.transactionsCountTooltip": "Количество записанных транзакций",
"udapp.transactionSaveTooltip1": "Нет транзакций для сохранения",
"udapp.transactionSaveTooltip2": "Сохранить транзакцию {count} как файл сценария",
"udapp.transactionSaveTooltip3": "Сохранить транзакции {count} как файл сценария",
"udapp.transactionsWalkthroughTooltip": "Начать пошаговое описание для записи.",
"udapp.infoRecorderTooltip": "Сохранить транзакции (развернутые контракты и выполнение функций) и повторить их в другой среде. Например, транзакции, созданные в Remix VM, могут воспроизводиться во внутреннем провайдере (Injected Provider).",
"udapp.livemodeRecorderTooltip": "Если контракты обновляются после записи транзакций, то установка этого флажка приведёт к запуску записанных транзакций с последней копией скомпилированных контрактов",
"udapp.livemodeRecorderLabel": "Выполнить транзакции с использованием последнего результата компиляции",
"udapp.runRecorderTooltip": "Выполнить транзакцию(и) из текущего файла сценария",
"udapp.save": "Сохранить",
"udapp.run": "Запустить",
"udapp._comment_contractGUI.tsx": "libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx",
"udapp.parameters": "Параметры",
"udapp.copyParameters": "Копировать параметры ввода в буфер обмена",
"udapp.copyCalldata": "Копировать данные вызова в буфер обмена",
"udapp.deployWithProxy": "Развернуть с прокси",
"udapp.upgradeWithProxy": "Обновить с прокси",
"udapp.getEncodedCallError": "невозможно кодировать пустые аргументы",
"udapp.proxyAddressError1": "прокси адрес не может быть пустым",
"udapp.proxyAddressError2": "недействительный адрес контракта",
"udapp.tooltipText11": "Прокси адрес не может быть пустым",
"udapp.tooltipText12": "Требуется ввод",
"udapp.tooltipText13": "Развернуто {date}",
"udapp._comment_universalDappUI.tsx": "libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx",
"udapp.tooltipText7": "Удалить из списка",
"udapp.tooltipText8": "Нажмите для просмотра документации об использовании функций 'receive'/'fallback'",
"udapp.tooltipText9": "Данные вызова для отправки в резервную функцию контракта.",
"udapp.tooltipText10": "Отправить данные контракту.",
"udapp.balance": "Баланс",
"udapp.lowLevelInteractions": "Взаимодействия низкого уровня",
"udapp.llIError1": "Отправляемое значение должно быть числом",
"udapp.llIError2": "Для получения перевода Ether контракт должен иметь функцию 'receive' или оплачиваемую функцию 'fallback'",
"udapp.llIError3": "Вызываемые данные должны быть допустимым шестнадцатеричным значением с размером не менее одного байта.",
"udapp.llIError4": "Вызываемые данные должны быть допустимым шестнадцатеричным значением.",
"udapp.llIError5": "Функция 'Fallback' не определена",
"udapp.llIError6": "Обе функции 'receive' и 'fallback' не определены",
"udapp.llIError7": "Пожалуйста, определите функцию 'Fallback' для отправки вызываемых данных или 'Receive' или оплачиваемую функцию 'Fallback' для отправки эфира",
"udapp.copy": "Копировать",
"udapp._comment_mainnet.tsx": "libs/remix-ui/run-tab/src/lib/components/mainnet.tsx",
"udapp.mainnetText1": "Вы собираетесь создать транзакцию в сети {name}. Подтвердите данные для отправки информации вашему провайдеру.",
"udapp.mainnetText2": "Провайдером для многих пользователей является MetaMask. Провайдер попросит вас подписать транзакцию перед отправкой ее в сеть {name}.",
"udapp.amount": "Количество",
"udapp.gasEstimation": "Оценка газа",
"udapp.maxPriorityFee": "Максимальная плата за приоритет",
"udapp.maxFee": "Максимальная комиссия (не меньше базовой комиссии {baseFeePerGas} Gwei)",
"udapp.contractCreation": "Создание контракта",
"udapp.transactionFee": "Недопустимая операция. Максимальная комиссия не должна быть меньше базовой комиссии",
"udapp.title1": "Представляет собой часть комиссии, которая направляется майнеру",
"udapp.title2": "Представляет максимальную сумму комиссии, которую вы платите за эту транзакцию. Минимальная сумма должна быть равной базовой комиссии.",
"udapp.gasPrice": "Цена газа",
"udapp.gweiText": "посетите {a} для информации о текущей цене газа.",
"udapp.maxTransactionFee": "Максимальная комиссия за транзакцию",
"udapp.mainnetText3": "Больше не показывать это предупреждение.",
"udapp._comment_run-tab.tsx": "libs/remix-ui/run-tab/src/lib/run-tab.tsx",
"udapp.gasEstimationPromptText": "При оценке газа произошла ошибка со следующим сообщением (см. ниже). Выполнение транзакции скорее всего закончится неудачно. Хотите принудительно отправить?",
"udapp._comment_custom-dropdown.tsx": "libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx",
"udapp.enterProxyAddress": "Введите адрес прокси",
"udapp._comment_provider": "apps/remix-ide/src/app/providers",
"udapp.customVmForkProviderText": "Пожалуйста, предоставьте информацию о пользовательском форке. Если URL-адрес узла не указан, Виртуальная Машина запустится с пустого состояния.",
"udapp.nodeUrl": "URL узла",
"udapp.blockNumber": "Номер блока (или \"последний\")",
"udapp.externalHttpProviderText1": "Примечание: Для использования Geth и https://remix.ethereum.org, настройте его так, чтобы он разрешал запросы от Remix:(см. <a>Geth Docs на сервере rpc</a>)",
"udapp.externalHttpProviderText2": "Для запуска Remix и локального тестового узла Geth используйте эту команду: (см. <a>Geth Docs в режиме Dev mode </a>)",
"udapp.externalHttpProviderText3": "<b>ВНИМАНИЕ:</b> Не безопасно использование флага --http.corsdomain с подстановочным символом: <b>--http.corsdomain *</b>",
"udapp.externalHttpProviderText4": "Для дополнительной информации: <a>Remix Docs на внешнем HTTP провайдере</a>",
"udapp.foundryProviderText1": "Примечание: Чтобы запустить Anvil в системе, запустите:",
"udapp.foundryProviderText2": "Для получения дополнительной информации, посетите <a>Документация по инструментарию разработки смарт-контрактов (Foundry) </a>",
"udapp.ganacheProviderText1": "Примечание: Чтобы запустить Ganache в системе, запустите:",
"udapp.ganacheProviderText2": "Для получения дополнительной информации, посетите: <a>Документация по Ganache</a>",
"udapp.hardhatProviderText1": "Примечание: Для запуска узла Hardhat в вашей системе, перейдите в папку hardhat проекта и запустите команду:",
"udapp.hardhatProviderText2": "Для получения дополнительной информации, посетите: <a>Документация по Hardhat</a>"
}

@ -1,7 +1,10 @@
import React from 'react' // eslint-disable-line
import {RunTabUI} from '@remix-ui/run-tab'
import {ViewPlugin} from '@remixproject/engine-web'
import isElectron from 'is-electron'
import {addressToString} from '@remix-ui/helper'
import {InjectedProviderDefault} from '../providers/injected-provider-default'
import {InjectedCustomProvider} from '../providers/injected-custom-provider'
import * as packageJson from '../../../../../package.json'
const EventManager = require('../../lib/events')
@ -28,17 +31,18 @@ const profile = {
'getSettings',
'setEnvironmentMode',
'clearAllInstances',
'clearAllSavedInstances',
'clearAllPinnedInstances',
'addInstance',
'addSavedInstance',
'addPinnedInstance',
'resolveContractAndAddInstance'
]
}
export class RunTab extends ViewPlugin {
constructor(blockchain, config, fileManager, editor, filePanel, compilersArtefacts, networkModule, fileProvider) {
constructor(blockchain, config, fileManager, editor, filePanel, compilersArtefacts, networkModule, fileProvider, engine) {
super(profile)
this.event = new EventManager()
this.engine = engine
this.config = config
this.blockchain = blockchain
this.fileManager = fileManager
@ -81,16 +85,16 @@ export class RunTab extends ViewPlugin {
this.emit('clearAllInstancesReducer')
}
clearAllSavedInstances() {
this.emit('clearAllSavedInstancesReducer')
clearAllPinnedInstances() {
this.emit('clearAllPinnedInstancesReducer')
}
addInstance(address, abi, name, contractData) {
this.emit('addInstanceReducer', address, abi, name, contractData)
}
addSavedInstance(address, abi, name, savedOn, filePath) {
this.emit('addSavedInstanceReducer', address, abi, name, savedOn, filePath)
addPinnedInstance(address, abi, name, pinnedAt, filePath) {
this.emit('addPinnedInstanceReducer', address, abi, name, pinnedAt, filePath)
}
createVMAccount(newAccount) {
@ -125,8 +129,9 @@ export class RunTab extends ViewPlugin {
async onInitDone() {
const udapp = this // eslint-disable-line
const addProvider = async (name, displayName, isInjected, isVM, fork = '', dataId = '', title = '') => {
const addProvider = async (position, name, displayName, isInjected, isVM, fork = '', dataId = '', title = '') => {
await this.call('blockchain', 'addProvider', {
position,
options: {},
dataId,
name,
@ -150,59 +155,73 @@ export class RunTab extends ViewPlugin {
})
}
// basic injected
// if it's the trust wallet provider, we have a specific provider for that, see below
if (window && window.ethereum && !(window.ethereum.isTrustWallet || window.ethereum.selectedProvider?.isTrustWallet)) {
const displayNameInjected = `Injected Provider${
window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)
? window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet
? ' - Coinbase'
: window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet
? ' - Brave'
: window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask
? ' - MetaMask'
: ''
: ''
}`
await addProvider('injected', displayNameInjected, true, false)
} else if (window && !window.ethereum) {
// we still add "injected" if there's no provider (just so it's visible to the user).
await addProvider('injected', 'Injected Provider', true, false)
const addCustomInjectedProvider = async (position, event, name, displayName, networkId, urls, nativeCurrency) => {
// name = `${name} through ${event.detail.info.name}`
await this.engine.register([new InjectedCustomProvider(event.detail.provider, name, networkId, urls, nativeCurrency)])
await addProvider(position, name, displayName, true, false, false)
}
const registerInjectedProvider = async (event) => {
console.log('registerInjectedProvider', event)
const name = 'injected-' + event.detail.info.name
const displayName = 'Injected Provider - ' + event.detail.info.name
await this.engine.register([new InjectedProviderDefault(event.detail.provider, name)])
await addProvider(0, name, displayName, true, false, false)
if (event.detail.info.name === 'MetaMask') {
await addCustomInjectedProvider(7, event, 'injected-metamask-optimism', 'L2 - Optimism', '0xa', ['https://mainnet.optimism.io'])
await addCustomInjectedProvider(8, event, 'injected-metamask-arbitrum', 'L2 - Arbitrum', '0xa4b1', ['https://arb1.arbitrum.io/rpc'])
await addCustomInjectedProvider(5, event, 'injected-metamask-sepolia', 'Testnet - Sepolia', '0xaa36a7', [],
{
"name": "Sepolia ETH",
"symbol": "ETH",
"decimals": 18
})
await addCustomInjectedProvider(9, event, 'injected-metamask-ephemery', 'Ephemery Testnet', '', ['https://otter.bordel.wtf/erigon', 'https://eth.ephemeral.zeus.fyi'],
{
"name": "Ephemery ETH",
"symbol": "ETH",
"decimals": 18
})
/*
await addCustomInjectedProvider(9, event, 'SKALE Chaos Testnet', '0x50877ed6', ['https://staging-v3.skalenodes.com/v1/staging-fast-active-bellatrix'],
{
"name": "sFUEL",
"symbol": "sFUEL",
"decimals": 18
})
*/
}
if (window && window.trustwallet) {
const displayNameInjected = `Injected Provider - TrustWallet`
await addProvider('injected-trustwallet', displayNameInjected, true, false)
}
// VM
const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.'
await addProvider('vm-cancun', 'Remix VM (Cancun)', false, true, 'cancun', 'settingsVMCancunMode', titleVM)
await addProvider('vm-shanghai', 'Remix VM (Shanghai)', false, true, 'shanghai', 'settingsVMShanghaiMode', titleVM)
await addProvider('vm-paris', 'Remix VM (Paris)', false, true, 'paris', 'settingsVMParisMode', titleVM)
await addProvider('vm-london', 'Remix VM (London)', false, true, 'london', 'settingsVMLondonMode', titleVM)
await addProvider('vm-berlin', 'Remix VM (Berlin)', false, true, 'berlin', 'settingsVMBerlinMode', titleVM)
await addProvider('vm-mainnet-fork', 'Remix VM - Mainnet fork', false, true, 'cancun', 'settingsVMMainnetMode', titleVM)
await addProvider('vm-sepolia-fork', 'Remix VM - Sepolia fork', false, true, 'cancun', 'settingsVMSepoliaMode', titleVM)
await addProvider('vm-goerli-fork', 'Remix VM - Goerli fork', false, true, 'paris', 'settingsVMGoerliMode', titleVM)
await addProvider('vm-custom-fork', 'Remix VM - Custom fork', false, true, '', 'settingsVMCustomMode', titleVM)
await addProvider(1, 'vm-cancun', 'Remix VM (Cancun)', false, true, 'cancun', 'settingsVMCancunMode', titleVM)
await addProvider(50, 'vm-shanghai', 'Remix VM (Shanghai)', false, true, 'shanghai', 'settingsVMShanghaiMode', titleVM)
await addProvider(51, 'vm-paris', 'Remix VM (Paris)', false, true, 'paris', 'settingsVMParisMode', titleVM)
await addProvider(52, 'vm-london', 'Remix VM (London)', false, true, 'london', 'settingsVMLondonMode', titleVM)
await addProvider(53, 'vm-berlin', 'Remix VM (Berlin)', false, true, 'berlin', 'settingsVMBerlinMode', titleVM)
await addProvider(2, 'vm-mainnet-fork', 'Remix VM - Mainnet fork', false, true, 'cancun', 'settingsVMMainnetMode', titleVM)
await addProvider(3, 'vm-sepolia-fork', 'Remix VM - Sepolia fork', false, true, 'cancun', 'settingsVMSepoliaMode', titleVM)
await addProvider(4, 'vm-custom-fork', 'Remix VM - Custom fork', false, true, '', 'settingsVMCustomMode', titleVM)
// wallet connect
await addProvider('walletconnect', 'WalletConnect', false, false)
// testnet
await addProvider('injected-ephemery-testnet-provider', 'Ephemery Testnet', true, false)
await addProvider('injected-skale-chaos-testnet-provider', 'SKALE Chaos Testnet', true, false)
await addProvider(6, 'walletconnect', 'WalletConnect', false, false)
// external provider
await addProvider('basic-http-provider', 'Custom - External Http Provider', false, false)
await addProvider('hardhat-provider', 'Dev - Hardhat Provider', false, false)
await addProvider('ganache-provider', 'Dev - Ganache Provider', false, false)
await addProvider('foundry-provider', 'Dev - Foundry Provider', false, false)
// injected provider
await addProvider('injected-optimism-provider', 'L2 - Optimism Provider', true, false)
await addProvider('injected-arbitrum-one-provider', 'L2 - Arbitrum One Provider', true, false)
await addProvider(10, 'basic-http-provider', 'Custom - External Http Provider', false, false)
await addProvider(20, 'hardhat-provider', 'Dev - Hardhat Provider', false, false)
await addProvider(21, 'ganache-provider', 'Dev - Ganache Provider', false, false)
await addProvider(22, 'foundry-provider', 'Dev - Foundry Provider', false, false)
// register injected providers
window.addEventListener(
"eip6963:announceProvider",
(event) => {
registerInjectedProvider(event)
}
)
if (!isElectron()) window.dispatchEvent(new Event("eip6963:requestProvider"))
}
writeFile(fileName, content) {

@ -66,6 +66,19 @@ body {
text-align:left;
background-color:#fff
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
background-color: var(--body-bg);
}
*::-webkit-scrollbar-thumb {
background-color: var(--secondary);
opacity: 0.3;
border-radius: 30px;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline:0!important
}

@ -67,6 +67,19 @@ body {
text-align:left;
background-color:#060606
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
background-color: var(--body-bg);
}
*::-webkit-scrollbar-thumb {
background-color: var(--secondary);
opacity: 0.3;
border-radius: 30px;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline:0!important
}
@ -5635,7 +5648,7 @@ a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover {
background-color:#090909!important
}
.bg-dark {
background-color:#adafae!important
background-color:#2f3130!important
}
a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover {
background-color:#939695!important

@ -65,6 +65,19 @@ body {
text-align:left;
background-color:#fff
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
background-color: var(--body-bg);
}
*::-webkit-scrollbar-thumb {
background-color: var(--secondary);
opacity: 0.3;
border-radius: 30px;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline:0!important
}

@ -69,6 +69,19 @@ body {
text-align:left;
background-color:#fff
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
background-color: var(--body-bg);
}
*::-webkit-scrollbar-thumb {
background-color: var(--secondary);
opacity: 0.3;
border-radius: 30px;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline:0!important
}

@ -74,6 +74,7 @@ body {
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
}
*::-webkit-scrollbar-thumb {
background-color: #37373b;

@ -14,7 +14,7 @@
--gray: #6c757d;
--gray-dark: #343a40;
--primary: #fc58a3;
--secondary: #e2f5f2;
--secondary: #c7e3de;
--success: #24b882;
--info: #00bbff;
--warning: #fabe33;
@ -76,6 +76,18 @@ body {
background-color: var(--body-bg);
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
background-color: var(--body-bg);
}
*::-webkit-scrollbar-thumb {
background-color: var(--secondary);
opacity: 0.3;
border-radius: 30px;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}

@ -74,6 +74,7 @@ body {
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
}
*::-webkit-scrollbar-thumb {
background-color: #41455b;

@ -91,6 +91,7 @@ body {
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
}
*::-webkit-scrollbar-thumb {
background-color: #41455b;

@ -76,6 +76,18 @@ body {
background-color: var(--body-bg);
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
background-color: var(--body-bg);
}
*::-webkit-scrollbar-thumb {
background-color: var(--secondary);
opacity: 0.3;
border-radius: 30px;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}

@ -76,6 +76,18 @@ body {
background-color: var(--body-bg);
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
background-color: var(--body-bg);
}
*::-webkit-scrollbar-thumb {
background-color: var(--secondary);
opacity: 0.3;
border-radius: 30px;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}

@ -76,6 +76,18 @@ body {
background-color: var(--body-bg);
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
background-color: var(--body-bg);
}
*::-webkit-scrollbar-thumb {
background-color: var(--secondary);
opacity: 0.3;
border-radius: 30px;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}

@ -76,6 +76,18 @@ body {
background-color: var(--body-bg);
}
*::-webkit-scrollbar {
width: 8px;
height: 6px;
background-color: var(--body-bg);
}
*::-webkit-scrollbar-thumb {
background-color: var(--secondary);
opacity: 0.3;
border-radius: 30px;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}

@ -61,6 +61,7 @@ export class Blockchain extends Plugin {
}
providers: {[key: string]: VMProvider | InjectedProvider | NodeProvider}
transactionContextAPI: TransactionContextAPI
registeredPluginEvents: string[]
// NOTE: the config object will need to be refactored out in remix-lib
constructor(config: Config) {
@ -91,6 +92,7 @@ export class Blockchain extends Plugin {
this.networkcallid = 0
this.networkStatus = {network: {name: ' - ', id: ' - '}}
this.registeredPluginEvents = []
this.setupEvents()
this.setupProviders()
}
@ -103,34 +105,24 @@ export class Blockchain extends Plugin {
onActivation() {
this.active = true
this.on('injected', 'chainChanged', () => {
this.on('manager', 'pluginActivated', (plugin) => {
if (plugin && plugin.name && (plugin.name.startsWith('injected') || plugin.name === 'walletconnect')) {
this.registeredPluginEvents.push(plugin.name)
this.on(plugin.name, 'chainChanged', () => {
this.detectNetwork((error, network) => {
this.networkStatus = {network, error}
this._triggerEvent('networkStatus', [this.networkStatus])
})
})
this.on('injected-trustwallet', 'chainChanged', () => {
this.detectNetwork((error, network) => {
this.networkStatus = {network, error}
this._triggerEvent('networkStatus', [this.networkStatus])
})
})
this.on('walletconnect', 'chainChanged', () => {
this.detectNetwork((error, network) => {
this.networkStatus = {network, error}
this._triggerEvent('networkStatus', [this.networkStatus])
})
}
})
}
onDeactivation() {
this.active = false
this.off('injected', 'chainChanged')
this.off('injected-trustwallet', 'chainChanged')
this.off('walletconnect', 'chainChanged')
this.off('walletconnect', 'accountsChanged')
for (const pluginName of this.registeredPluginEvents) {
this.off(pluginName, 'chainChanged')
}
}
setupEvents() {
@ -175,6 +167,7 @@ export class Blockchain extends Plugin {
getCurrentProvider() {
const provider = this.getProvider()
if (provider && provider.startsWith('vm')) return this.providers['vm']
if (provider && provider.startsWith('injected')) return this.providers['injected']
if (this.providers[provider]) return this.providers[provider]
return this.providers.web3 // default to the common type of provider
}
@ -534,16 +527,6 @@ export class Blockchain extends Plugin {
return this.executionContext.getCurrentFork()
}
isWeb3Provider() {
const isVM = this.executionContext.isVM()
const isInjected = this.getProvider() === 'injected'
return !isVM && !isInjected
}
isInjectedWeb3() {
return this.getProvider() === 'injected'
}
signMessage(message, account, passphrase, cb) {
this.getCurrentProvider().signMessage(message, account, passphrase, cb)
}

@ -48,8 +48,4 @@ export class InjectedProvider {
cb(e.message)
}
}
getProvider () {
return 'injected'
}
}

@ -55,8 +55,4 @@ export class NodeProvider {
cb(e.message)
}
}
getProvider () {
return this.executionContext.getProvider()
}
}

@ -135,8 +135,4 @@ export class VMProvider {
.then(signedData => cb(null, bytesToHex(messageHash), signedData))
.catch(error => cb(error))
}
getProvider () {
return this.executionContext.getProvider()
}
}

@ -52,12 +52,6 @@ let requiredModules = [ // services + layout views + system views
'ganache-provider',
'foundry-provider',
'basic-http-provider',
'injected',
'injected-trustwallet',
'injected-optimism-provider',
'injected-arbitrum-one-provider',
'injected-ephemery-testnet-provider',
'injected-skale-chaos-testnet-provider',
'vm-custom-fork',
'vm-goerli-fork',
'vm-mainnet-fork',
@ -98,7 +92,16 @@ const sensitiveCalls = {
web3Provider: ['sendAsync']
}
const isInjectedProvider = (name) => {
return name.startsWith('injected')
}
const isVM = (name) => {
return name.startsWith('vm')
}
export function isNative(name) {
// nativePlugin allows to bypass the permission request
const nativePlugins = [
'vyper',
@ -117,19 +120,16 @@ export function isNative(name) {
'ganache-provider',
'foundry-provider',
'basic-http-provider',
'injected-optimism-provider',
'tabs',
'injected-arbitrum-one-provider',
'injected-skale-chaos-testnet-provider',
'injected-ephemery-testnet-provider',
'injected',
'doc-gen',
'doc-viewer',
'circuit-compiler',
'compilationDetails',
'vyperCompilationDetails'
'vyperCompilationDetails',
'remixGuide',
'walletconnect'
]
return nativePlugins.includes(name) || requiredModules.includes(name)
return nativePlugins.includes(name) || requiredModules.includes(name) || isInjectedProvider(name) || isVM(name)
}
/**
@ -163,7 +163,7 @@ export class RemixAppManager extends PluginManager {
}
async canDeactivatePlugin(from, to) {
if (requiredModules.includes(to.name)) return false
if (this.isRequired(to.name)) return false
return isNative(from.name)
}
@ -208,7 +208,7 @@ export class RemixAppManager extends PluginManager {
)
this.event.emit('activate', plugin)
this.emit('activate', plugin)
if (!requiredModules.includes(plugin.name)) _paq.push(['trackEvent', 'pluginManager', 'activate', plugin.name])
if (!this.isRequired(plugin.name)) _paq.push(['trackEvent', 'pluginManager', 'activate', plugin.name])
}
getAll() {
@ -236,7 +236,7 @@ export class RemixAppManager extends PluginManager {
isRequired(name) {
// excluding internal use plugins
return requiredModules.includes(name)
return requiredModules.includes(name) || isInjectedProvider(name) || isVM(name)
}
async registeredPlugins() {

@ -47,6 +47,7 @@ const App = () => {
try {
await remixClient.loaded()
remixClient.onFileChange((name) => {
!name.endsWith('.vy') && remixClient.changeStatus({ key: 'none' })
setOutput({})
setContract(name)
})
@ -116,9 +117,9 @@ const App = () => {
<main id="vyper-plugin">
<section>
<div className="px-3 pt-3 mb-3 w-100">
<CustomTooltip placement="bottom" tooltipText="Clone Vyper examples. Switch to the File Explorer to see the examples.">
<CustomTooltip placement="bottom" tooltipText="Clone a repo of Vyper examples. Switch to the File Explorer to see the examples.">
<Button data-id="add-repository" className="w-100 btn btn-secondary" onClick={() => remixClient.cloneVyperRepo()}>
Clone Vyper examples repository
Clone a repo of Vyper examples
</Button>
</CustomTooltip>
</div>
@ -155,13 +156,13 @@ const App = () => {
compiler version
</a>{' '}
&{' '}
<a className="text-warning" href="http://docs.vyperlang.org/en/stable/compiling-a-contract.html#setting-the-target-evm-version" target="_blank" rel="noopener noreferrer">
<a className="text-warning" href="https://remix-ide.readthedocs.io/en/latest/vyper.html#evm-version" target="_blank" rel="noopener noreferrer">
EVM version
</a>{' '}
in the .vy file.
</span>
<div className="px-3 w-100 mb-3 mt-1" id="compile-btn">
<CompilerButton compilerUrl={compilerUrl()} contract={contract} setOutput={(name, update) => setOutput({...output, [name]: update})} resetCompilerState={resetCompilerResultState} />
<CompilerButton compilerUrl={compilerUrl()} contract={contract} setOutput={(name, update) => setOutput({...output, [name]: update})} resetCompilerState={resetCompilerResultState} output={output} remixClient={remixClient}/>
</div>
<article id="result" className="p-2 mx-3 border-top mt-2">

@ -7,7 +7,6 @@ export function CompileErrorCard(props: { output: any, plugin: RemixClient }) {
<div
id="vyperErrorResult"
className=" d-flex flex-column p-2 alert alert-danger error vyper-compile-error vyper-panel-width"
title={props.output?.title}
>
<span
data-id="error-message"
@ -21,7 +20,7 @@ export function CompileErrorCard(props: { output: any, plugin: RemixClient }) {
</span>
<div className="d-flex flex-column pt-3 align-items-end mb-2">
<div>
<span className="border border-success text-success btn-sm" onClick={async () => await props.plugin.askGpt(props.output.message)}>
<span className="border border-ai text-ai btn-sm" onClick={async () => await props.plugin.askGpt(props.output.message)}>
Ask GPT
</span>
<span className="ml-3 pt-1 py-1">

@ -1,16 +1,19 @@
import React, { Fragment, useState } from 'react'
import {isVyper, compile, toStandardOutput, isCompilationError, remixClient, normalizeContractPath, compileContract} from '../utils'
import React, { Fragment, useEffect, useState } from 'react'
import {isVyper, compile, toStandardOutput, isCompilationError, remixClient, normalizeContractPath, compileContract, RemixClient} from '../utils'
import Button from 'react-bootstrap/Button'
interface Props {
compilerUrl: string
contract?: string
output?: any
setOutput: (name: string, output: any) => void
resetCompilerState: () => void
remixClient: RemixClient
}
function CompilerButton({contract, setOutput, compilerUrl, resetCompilerState}: Props) {
function CompilerButton({contract, setOutput, compilerUrl, resetCompilerState, output, remixClient}: Props) {
const [loadingSpinner, setLoadingSpinnerState] = useState(false)
if (!contract || !contract) {
return <Button disabled className="w-100">No contract selected</Button>
}
@ -24,12 +27,14 @@ function CompilerButton({contract, setOutput, compilerUrl, resetCompilerState}:
return (
<Fragment>
<button data-id="compile"
onClick={() => compileContract(contract, compilerUrl, setOutput)}
title={contract}
onClick={async () => {
setLoadingSpinnerState(true)
await compileContract(contract, compilerUrl, setOutput, setLoadingSpinnerState)
}}
className="btn btn-primary w-100 d-block btn-block text-break remixui_disabled mb-1 mt-3"
>
<div className="d-flex align-items-center justify-content-center fa-1x">
{/* <span className="fas fa-sync fa-pulse mr-1" /> */}
<span className={ loadingSpinner ? 'fas fa-sync fa-pulse mr-1' : 'fas fa-sync mr-1'} />
<div className="text-truncate overflow-hidden text-nowrap">
<span>Compile</span>
<span className="ml-1 text-nowrap">{contract}</span>

@ -144,14 +144,18 @@ const compileReturnType = (output, contract) => {
const fixContractContent = (content: string) => {
if (content.length === 0) return
const pragmaFound = content.includes('#pragma version ^0.3.10')
const wrongpragmaFound = content.includes('# pragma version ^0.3.10')
const evmVerFound = content.includes('#pragma evm-version shanghai')
const pragma = '#pragma version ^0.3.10'
const evmVer = '#pragma evm-version shanghai'
if (!evmVerFound) {
if (evmVerFound === false) {
content = `${evmVer}\n${content}`
}
if (!pragmaFound) {
if (wrongpragmaFound === true) {
content = content.replace('# pragma version ^0.3.10', '')
}
if (pragmaFound === false ) {
content = `${pragma}\n${content}`
}
return content
@ -263,8 +267,9 @@ export function toStandardOutput(fileName: string, compilationResult: any): any
}
export async function compileContract(contract: string, compilerUrl: string, setOutput?: any) {
export async function compileContract(contract: string, compilerUrl: string, setOutput?: any, setLoadingSpinnerState?: React.Dispatch<React.SetStateAction<boolean>>, spinner?: boolean) {
remixClient.eventEmitter.emit('resetCompilerState', {})
spinner && spinner === true ? setLoadingSpinnerState && setLoadingSpinnerState(true) : null
try {
// await remixClient.discardHighlight()
@ -276,6 +281,7 @@ export async function compileContract(contract: string, compilerUrl: string, set
status: 'failed',
message: e.message
}
remixClient.eventEmitter.emit('setOutput', errorGettingContract)
return
}
@ -293,7 +299,9 @@ export async function compileContract(contract: string, compilerUrl: string, set
type: 'error',
title: 'Compilation failed...'
})
remixClient.eventEmitter.emit('setOutput', {status: 'failed', message: output.message, title: 'Error compiling...', line: output.line, column: output.column})
setLoadingSpinnerState && setLoadingSpinnerState(false)
remixClient.eventEmitter.emit('setOutput', {status: 'failed', message: output.message, title: 'Error compiling...', line: output.line, column: output.column, key: 1 })
output = null
return
}
@ -306,6 +314,7 @@ export async function compileContract(contract: string, compilerUrl: string, set
title: 'success'
})
setLoadingSpinnerState && setLoadingSpinnerState(false)
const data = toStandardOutput(_contract.name, output)
remixClient.compilationFinish(_contract.name, _contract.content, data)
const contractName = _contract['name']
@ -319,8 +328,10 @@ export async function compileContract(contract: string, compilerUrl: string, set
remixClient.changeStatus({
key: 'failed',
type: 'error',
title: err.message
title: `1 error occurred ${err.message}`
})
setLoadingSpinnerState && setLoadingSpinnerState(false)
remixClient.eventEmitter.emit('setOutput', {status: 'failed', message: err.message})
}
}

@ -80,20 +80,20 @@ export class RemixClient extends PluginClient {
async cloneVyperRepo() {
try {
// @ts-ignore
this.call('notification', 'toast', 'cloning Vyper repository...')
this.call('notification', 'toast', 'cloning Snekmate Vyper repository...')
await this.call('manager', 'activatePlugin', 'dGitProvider')
await this.call(
'dGitProvider',
'clone',
{url: 'https://github.com/vyperlang/vyper', token: null, branch: 'v0.3.10'},
{url: 'https://github.com/pcaversaccio/snekmate', token: null, branch: 'v0.0.5'},
// @ts-ignore
'vyper-lang'
'snekmate'
)
this.call(
// @ts-ignore
'notification',
'toast',
'Vyper repository cloned, the workspace Vyper has been created.'
'Snekmate Vyper repository cloned, the workspace snekmate has been created.'
)
} catch (e) {
// @ts-ignore

@ -1,6 +1,6 @@
{
"name": "@remix-project/ghaction-helper",
"version": "0.1.26",
"version": "0.1.28",
"description": "Solidity Tests GitHub Action Helper",
"main": "src/index.js",
"scripts": {
@ -19,17 +19,17 @@
},
"homepage": "https://github.com/ethereum/remix-project#readme",
"devDependencies": {
"@remix-project/remix-solidity": "^0.5.32",
"@remix-project/remix-solidity": "^0.5.34",
"@types/chai": "^4.3.4",
"typescript": "^4.9.3"
},
"dependencies": {
"@ethereum-waffle/chai": "^3.4.4",
"@remix-project/remix-simulator": "^0.2.46",
"@remix-project/remix-simulator": "^0.2.48",
"chai": "^4.3.7",
"ethers": "^5.7.2",
"web3": "^4.1.1"
},
"types": "./src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd"
"gitHead": "4f5c2cb88bc38099f71c5407265a23ab3bb7508e"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-analyzer",
"version": "0.5.55",
"version": "0.5.57",
"description": "Tool to perform static analysis on Solidity smart contracts",
"scripts": {
"test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts"
@ -25,8 +25,8 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-astwalker": "^0.0.76",
"@remix-project/remix-lib": "^0.5.53",
"@remix-project/remix-astwalker": "^0.0.78",
"@remix-project/remix-lib": "^0.5.55",
"async": "^2.6.2",
"ethers": "^5.4.2",
"ethjs-util": "^0.1.6",
@ -50,6 +50,6 @@
"typescript": "^3.7.5"
},
"typings": "src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd",
"gitHead": "4f5c2cb88bc38099f71c5407265a23ab3bb7508e",
"main": "./src/index.js"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-astwalker",
"version": "0.0.76",
"version": "0.0.78",
"description": "Tool to walk through Solidity AST",
"main": "src/index.js",
"scripts": {
@ -37,7 +37,7 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-lib": "^0.5.53",
"@remix-project/remix-lib": "^0.5.55",
"@types/tape": "^4.2.33",
"async": "^2.6.2",
"ethers": "^5.4.2",
@ -53,6 +53,6 @@
"tap-spec": "^5.0.0"
},
"typings": "src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd",
"gitHead": "4f5c2cb88bc38099f71c5407265a23ab3bb7508e",
"types": "./src/index.d.ts"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-debug",
"version": "0.5.46",
"version": "0.5.48",
"description": "Tool to debug Ethereum transactions",
"contributors": [
{
@ -26,10 +26,10 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-astwalker": "^0.0.76",
"@remix-project/remix-lib": "^0.5.53",
"@remix-project/remix-simulator": "^0.2.46",
"@remix-project/remix-solidity": "^0.5.32",
"@remix-project/remix-astwalker": "^0.0.78",
"@remix-project/remix-lib": "^0.5.55",
"@remix-project/remix-simulator": "^0.2.48",
"@remix-project/remix-solidity": "^0.5.34",
"ansi-gray": "^0.1.1",
"async": "^2.6.2",
"color-support": "^1.1.3",
@ -69,6 +69,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme",
"typings": "src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd",
"gitHead": "4f5c2cb88bc38099f71c5407265a23ab3bb7508e",
"types": "./src/index.d.ts"
}

@ -96,7 +96,7 @@ export class CmdLine {
this.events.emit('globals', data)
})
// TODO: this doesnt work too well, it should request the data instead...
// TODO: this doesn't work too well, it should request the data instead...
this.debugger.vmDebuggerLogic.event.register('solidityLocals', (data) => {
if (JSON.stringify(data) === '{}') return
this.solidityLocals = data

@ -229,7 +229,7 @@ function getEnum (type, stateDefinitions, contractName) {
}
/**
* retrieve members declared in the given @arg tye
* retrieve members declared in the given @arg type
*
* @param {String} typeName - name of the struct type (e.g struct <name>)
* @param {Object} stateDefinitions - all state definition given by the AST (including struct and enum type declaration) for all contracts

@ -67,7 +67,7 @@ export class StorageViewer {
/**
* return all the possible mappings locations for the current context (cached) do not return state changes during the current transaction
*
* @param {Array} corrections - used in case the calculated sha3 has been modifyed before SSTORE (notably used for struct in mapping).
* @param {Array} corrections - used in case the calculated sha3 has been modified before SSTORE (notably used for struct in mapping).
*/
async initialMappingsLocation (corrections) {
if (!this.initialMappingsLocationPromise) {
@ -79,7 +79,7 @@ export class StorageViewer {
/**
* return all the possible mappings locations for the current context (cached) and current mapping slot. returns state changes during the current transaction
*
* @param {Array} corrections - used in case the calculated sha3 has been modifyed before SSTORE (notably used for struct in mapping).
* @param {Array} corrections - used in case the calculated sha3 has been modified before SSTORE (notably used for struct in mapping).
*/
async mappingsLocation (corrections) {
if (!this.currentMappingsLocationPromise) {
@ -94,7 +94,7 @@ export class StorageViewer {
/**
* retrieve mapping location changes from the storage changes.
* @param {Map} storageChanges
* @param {Array} corrections - used in case the calculated sha3 has been modifyed before SSTORE (notably used for struct in mapping).
* @param {Array} corrections - used in case the calculated sha3 has been modified before SSTORE (notably used for struct in mapping).
*/
extractMappingsLocationChanges (storageChanges, corrections) {
if (this.mappingsLocationChanges) {

@ -1,5 +1,6 @@
'use strict'
import { util } from '@remix-project/remix-lib'
import { bytesToHex } from '@ethereumjs/util'
const { toHexPaddedString } = util
import * as traceHelper from './traceHelper'
@ -85,7 +86,7 @@ export class TraceAnalyser {
offset = 2 * parseInt(toHexPaddedString(stack[stack.length - 4]), 16)
size = 2 * parseInt(toHexPaddedString(stack[stack.length - 5]), 16)
}
calldata = '0x' + memory.join('').substr(offset, size)
calldata = bytesToHex(memory).replace('0x', '').substring(offset, offset + size)
this.traceCache.pushCallDataChanges(index + 1, calldata)
}
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-lib",
"version": "0.5.53",
"version": "0.5.55",
"description": "Library to various Remix tools",
"contributors": [
{
@ -55,6 +55,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme",
"typings": "src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd",
"gitHead": "4f5c2cb88bc38099f71c5407265a23ab3bb7508e",
"types": "./src/index.d.ts"
}

@ -171,6 +171,6 @@ export function checkError (execResult, compiledContracts) {
msg = '\tState changes is not allowed in Static Call context\n'
ret.error = true
}
ret.message = `${error}\n${exceptionError}\n${msg}\nDebug the transaction to get more information.`
ret.message = `${error}\n${exceptionError}\n${msg}\nYou may want to cautiously increase the gas limit if the transaction went out of gas.`
return ret
}

@ -128,7 +128,14 @@ export class TxRunnerVM {
transactions: [tx]
}, { common: this.commonContext })
if (!this.standaloneTx) {
// standaloneTx represents a gas estimation call
if (this.standaloneTx || useCall) {
const root = await this.getVMObject().stateManager.getStateRoot()
this.runBlockInVm(tx, block, async (err, result) => {
await this.getVMObject().stateManager.setStateRoot(root)
callback(err, result)
})
} else {
this.blockParentHash = block.hash()
this.runBlockInVm(tx, block, async (err, result) => {
if (!err) {
@ -139,12 +146,6 @@ export class TxRunnerVM {
}
callback(err, result)
})
} else {
const root = await this.getVMObject().stateManager.getStateRoot()
this.runBlockInVm(tx, block, async (err, result) => {
await this.getVMObject().stateManager.setStateRoot(root)
callback(err, result)
})
}
} catch (e) {
callback(e)

@ -106,7 +106,6 @@ export class TxRunnerWeb3 {
const tx = { from: from, to: to, data: data, value: value }
if (!from) return callback('the value of "from" is not defined. Please make sure an account is selected.')
if (useCall) {
tx['gas'] = gasLimit
if (this._api && this._api.isVM()) {
(this.getWeb3() as any).remix.registerCallId(timestamp)
}
@ -137,8 +136,19 @@ export class TxRunnerWeb3 {
this.getWeb3().eth.estimateGas(txCopy)
.then(gasEstimation => {
gasEstimationForceSend(null, () => {
// callback is called whenever no error
tx['gas'] = !gasEstimation ? gasLimit : gasEstimation
/*
* gasLimit is a value that can be set in the UI to hardcap value that can be put in a tx.
* e.g if the gasestimate
*/
if (gasLimit !== '0x0' && gasEstimation > gasLimit) {
return callback(`estimated gas for this transaction (${gasEstimation}) is higher than gasLimit set in the configuration (${gasLimit}). Please raise the gas limit.`)
}
if (gasLimit === '0x0') {
tx['gas'] = gasEstimation
} else {
tx['gas'] = gasLimit
}
if (this._api.config.getUnpersistedProperty('doNotShowTransactionConfirmationAgain')) {
return this._executeTx(tx, network, null, this._api, promptCb, callback)
@ -158,7 +168,8 @@ export class TxRunnerWeb3 {
}
err = network.name === 'VM' ? null : err // just send the tx if "VM"
gasEstimationForceSend(err, () => {
tx['gas'] = gasLimit
const defaultGasLimit = 3000000
tx['gas'] = gasLimit === '0x0' ? '0x' + defaultGasLimit.toString(16) : gasLimit
if (this._api.config.getUnpersistedProperty('doNotShowTransactionConfirmationAgain')) {
return this._executeTx(tx, network, null, this._api, promptCb, callback)

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-simulator",
"version": "0.2.46",
"version": "0.2.48",
"description": "Ethereum IDE and tools for the web",
"contributors": [
{
@ -22,7 +22,7 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-lib": "^0.5.53",
"@remix-project/remix-lib": "^0.5.55",
"ansi-gray": "^0.1.1",
"async": "^3.1.0",
"body-parser": "^1.18.2",
@ -70,6 +70,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme",
"typings": "src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd",
"gitHead": "4f5c2cb88bc38099f71c5407265a23ab3bb7508e",
"types": "./src/index.d.ts"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-solidity",
"version": "0.5.32",
"version": "0.5.34",
"description": "Tool to load and run Solidity compiler",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -19,7 +19,7 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-lib": "^0.5.53",
"@remix-project/remix-lib": "^0.5.55",
"async": "^2.6.2",
"eslint-scope": "^5.0.0",
"ethers": "^5.4.2",
@ -57,5 +57,5 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme",
"typings": "src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd"
"gitHead": "4f5c2cb88bc38099f71c5407265a23ab3bb7508e"
}

@ -22,8 +22,8 @@ export class CompilerAbstract {
return helper.getContract(name, this.data.contracts)
}
visitContracts (calllback) {
return helper.visitContracts(this.data.contracts, calllback)
visitContracts (callback) {
return helper.visitContracts(this.data.contracts, callback)
}
getData () {

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-tests",
"version": "0.2.46",
"version": "0.2.48",
"description": "Tool to test Solidity smart contracts",
"main": "src/index.js",
"types": "./src/index.d.ts",
@ -41,9 +41,9 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-lib": "^0.5.53",
"@remix-project/remix-simulator": "^0.2.46",
"@remix-project/remix-solidity": "^0.5.32",
"@remix-project/remix-lib": "^0.5.55",
"@remix-project/remix-simulator": "^0.2.48",
"@remix-project/remix-solidity": "^0.5.34",
"@remix-project/remix-url-resolver": "^0.0.42",
"ansi-gray": "^0.1.1",
"async": "^2.6.0",
@ -89,5 +89,5 @@
"@ethereumjs/trie": "6.2.0"
},
"typings": "src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd"
"gitHead": "4f5c2cb88bc38099f71c5407265a23ab3bb7508e"
}

@ -106,7 +106,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
const providerChanged = () => {
debuggerModule.onEnvChanged((provider) => {
setState((prevState) => {
const isLocalNodeUsed = !provider.startsWith('vm') && provider !== 'injected'
const isLocalNodeUsed = !provider.startsWith('vm') && !provider.startsWith('injected')
return {...prevState, isLocalNodeUsed: isLocalNodeUsed}
})
})

@ -14,7 +14,7 @@ export const SolidityLocals = ({data, message, registerEvent, triggerEvent, clas
let color = 'var(--primary)'
if (data.isArray || data.isStruct || data.isMapping) {
color = 'var(--info)'
} else if (data.type.indexOf('uint') === 0 || data.type.indexOf('int') === 0 || data.type.indexOf('bool') === 0 || data.type.indexOf('enum') === 0) {
} else if (data.type && data.type.indexOf && (data.type.indexOf('uint') === 0 || data.type.indexOf('int') === 0 || data.type.indexOf('bool') === 0 || data.type.indexOf('enum') === 0)) {
color = 'var(--green)'
} else if (data.type === 'string') {
color = 'var(--teal)'
@ -41,7 +41,9 @@ export const SolidityLocals = ({data, message, registerEvent, triggerEvent, clas
</label>
)
}
if (calldata && Object.keys(calldata).length) {
message = ''
}
return (
<div className={className} id="soliditylocals" data-id="solidityLocals">
<DropdownPanel

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save