git4refactor
filip mertens 7 months ago
commit 5c0a0a610f
  1. 96
      .circleci/config.yml
  2. 2
      .github/workflows/pr-reminder.yml
  3. 1
      .gitignore
  4. 22
      README.md
  5. 4
      apps/learneth/README.md
  6. 42
      apps/remix-ide-e2e/install-webdriver.sh
  7. 46
      apps/remix-ide-e2e/nightwatch-chrome.ts
  8. 54
      apps/remix-ide-e2e/nightwatch-firefox.ts
  9. 1
      apps/remix-ide-e2e/package.json
  10. 73
      apps/remix-ide-e2e/src/commands/setupMetamask.ts
  11. 1
      apps/remix-ide-e2e/src/commands/switchBrowserTab.ts
  12. BIN
      apps/remix-ide-e2e/src/extensions/chrome/11.13.1_0.crx
  13. BIN
      apps/remix-ide-e2e/src/extensions/chrome/metamask.crx
  14. 2
      apps/remix-ide-e2e/src/helpers/init.ts
  15. 19
      apps/remix-ide-e2e/src/select_tests.sh
  16. 107
      apps/remix-ide-e2e/src/tests/circom.test.ts
  17. 106
      apps/remix-ide-e2e/src/tests/pinned_contracts.test.ts
  18. 128
      apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts
  19. 272
      apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts
  20. 30
      apps/remix-ide-e2e/src/tests/sol2uml.test.ts
  21. 1
      apps/remix-ide-e2e/src/tests/staticAnalysis.test.ts
  22. 183
      apps/remix-ide-e2e/src/tests/vyper_api.test.ts
  23. 14
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  24. 597
      apps/remix-ide-e2e/yarn.lock
  25. 2
      apps/remix-ide/ci/browser_test.sh
  26. 2
      apps/remix-ide/ci/browser_test_plugin.sh
  27. 2
      apps/remix-ide/ci/flaky.sh
  28. 22
      apps/remix-ide/src/app.js
  29. 44
      apps/remix-ide/src/app/plugins/solcoderAI.tsx
  30. 13
      apps/remix-ide/src/app/providers/injected-custom-provider.tsx
  31. 10
      apps/remix-ide/src/app/providers/injected-provider-default.tsx
  32. 6
      apps/remix-ide/src/app/tabs/locales/en/remixUiTabs.json
  33. 8
      apps/remix-ide/src/app/tabs/locales/en/udapp.json
  34. 71
      apps/remix-ide/src/app/udapp/run-tab.js
  35. 5
      apps/vyper/src/app/app.tsx
  36. 3
      apps/vyper/src/app/components/CompileErrorCard.tsx
  37. 17
      apps/vyper/src/app/components/CompilerButton.tsx
  38. 13
      apps/vyper/src/app/utils/compiler.tsx
  39. 8
      libs/ghaction-helper/package.json
  40. 8
      libs/remix-analyzer/package.json
  41. 6
      libs/remix-astwalker/package.json
  42. 12
      libs/remix-debug/package.json
  43. 2
      libs/remix-debug/src/cmdline/index.ts
  44. 2
      libs/remix-debug/src/solidity-decoder/decodeInfo.ts
  45. 6
      libs/remix-debug/src/storage/storageViewer.ts
  46. 3
      libs/remix-debug/src/trace/traceAnalyser.ts
  47. 4
      libs/remix-lib/package.json
  48. 15
      libs/remix-lib/src/execution/txRunnerVM.ts
  49. 6
      libs/remix-simulator/package.json
  50. 6
      libs/remix-solidity/package.json
  51. 4
      libs/remix-solidity/src/compiler/compiler-abstract.ts
  52. 10
      libs/remix-tests/package.json
  53. 6
      libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-locals.tsx
  54. 2
      libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-state.tsx
  55. 39
      libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts
  56. 18
      libs/remix-ui/run-tab/src/lib/actions/actions.ts
  57. 9
      libs/remix-ui/run-tab/src/lib/actions/deploy.ts
  58. 64
      libs/remix-ui/run-tab/src/lib/actions/events.ts
  59. 4
      libs/remix-ui/run-tab/src/lib/actions/index.ts
  60. 25
      libs/remix-ui/run-tab/src/lib/actions/payload.ts
  61. 7
      libs/remix-ui/run-tab/src/lib/components/account.tsx
  62. 139
      libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
  63. 55
      libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx
  64. 5
      libs/remix-ui/run-tab/src/lib/constants/index.ts
  65. 58
      libs/remix-ui/run-tab/src/lib/reducers/runTab.ts
  66. 4
      libs/remix-ui/run-tab/src/lib/run-tab.tsx
  67. 21
      libs/remix-ui/run-tab/src/lib/types/index.ts
  68. 2
      libs/remix-ui/settings/src/lib/remix-ui-settings.tsx
  69. 4
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
  70. 2
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  71. 4
      libs/remix-url-resolver/package.json
  72. 4
      libs/remix-ws-templates/package.json
  73. 10
      libs/remix-ws-templates/src/templates/hashchecker/README.md
  74. 10
      libs/remix-ws-templates/src/templates/hashchecker/index.ts
  75. 15
      libs/remix-ws-templates/src/templates/hashchecker/scripts/groth16/groth16_trusted_setup.ts
  76. 21
      libs/remix-ws-templates/src/templates/hashchecker/scripts/groth16/groth16_zkproof.ts
  77. 32
      libs/remix-ws-templates/src/templates/hashchecker/scripts/plonk/plonk_trusted_setup.ts
  78. 93
      libs/remix-ws-templates/src/templates/hashchecker/scripts/plonk/plonk_zkproof.ts
  79. 710
      libs/remix-ws-templates/src/templates/hashchecker/templates/plonk_verifier.sol.ejs
  80. 10
      libs/remix-ws-templates/src/templates/rln/index.ts
  81. 15
      libs/remix-ws-templates/src/templates/rln/scripts/groth16/groth16_trusted_setup.ts
  82. 26
      libs/remix-ws-templates/src/templates/rln/scripts/groth16/groth16_zkproof.ts
  83. 33
      libs/remix-ws-templates/src/templates/rln/scripts/plonk/plonk_trusted_setup.ts
  84. 183
      libs/remix-ws-templates/src/templates/rln/scripts/plonk/plonk_zkproof.ts
  85. 710
      libs/remix-ws-templates/src/templates/rln/templates/plonk_verifier.sol.ejs
  86. 12
      libs/remix-ws-templates/src/templates/semaphore/index.ts
  87. 53
      libs/remix-ws-templates/src/templates/semaphore/scripts/groth16/groth16_trusted_setup.ts
  88. 114
      libs/remix-ws-templates/src/templates/semaphore/scripts/groth16/groth16_zkproof.ts
  89. 37
      libs/remix-ws-templates/src/templates/semaphore/scripts/plonk/plonk_trusted_setup.ts
  90. 139
      libs/remix-ws-templates/src/templates/semaphore/scripts/plonk/plonk_zkproof.ts
  91. 710
      libs/remix-ws-templates/src/templates/semaphore/templates/plonk_verifier.sol.ejs
  92. 2
      libs/remixd/package.json
  93. 47
      package.json
  94. 10
      releaseDetails.json
  95. 245
      yarn.lock

@ -357,6 +357,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 >> ]
@ -366,10 +373,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 >> ]
@ -377,36 +382,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
@ -433,28 +412,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
@ -621,35 +591,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

@ -66,3 +66,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

@ -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']
}
}
},
'firefoxDesktop': {
desiredCapabilities: {
'browserName': 'firefox',
'javascriptEnabled': true,
'acceptSslCerts': true,
'moz:firefoxOptions': {
args: ['-width=2560', '-height=1440']
args: ['window-size=2560,1440', '--no-sandbox', '--verbose']
,extensions: [metamaskExtension]
}
}
},
'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": {

@ -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,26 +14,59 @@ 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')
.perform(() => {
done()
})
.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()
})
}

@ -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,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('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('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);
}
}`
}
}
]

@ -14,20 +14,20 @@ module.exports = {
.rightClick('*[data-id="treeViewLitreeViewItemTestBallot.sol"]')
.click('*[id="menuitemgeneratecustomaction"')
.waitForElementVisible('*[id="sol-uml-gen"]')
},
'Generate uml for contracts with imports #group1': function (browser: NightwatchBrowser) {
browser.addFile('secondContract.sol', sources[1]['secondContract.sol'])
.waitForElementVisible('*[data-id="treeViewLitreeViewItemsecondContract.sol"')
.pause(3000)
.rightClick('*[data-id="treeViewLitreeViewItemsecondContract.sol"]')
.click('*[id="menuitemgeneratecustomaction"')
.waitForElementVisible('*[id="sol-uml-gen"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemsecondContract_flattened.sol"]')
},
'Zoom into uml diagram #group1': function (browser: NightwatchBrowser) {
browser
.click('*[data-id="umlZoominbtn"]')
}
},
'Generate uml for contracts with imports #group1': function (browser: NightwatchBrowser) {
browser.addFile('secondContract.sol', sources[1]['secondContract.sol'])
.waitForElementVisible('*[data-id="treeViewLitreeViewItemsecondContract.sol"')
.pause(3000)
.rightClick('*[data-id="treeViewLitreeViewItemsecondContract.sol"]')
.click('*[id="menuitemgeneratecustomaction"')
.waitForElementVisible('*[id="sol-uml-gen"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemsecondContract_flattened.sol"]')
},
'Zoom into uml diagram #group1': function (browser: NightwatchBrowser) {
browser
.click('*[data-id="umlZoominbtn"]')
}
}
const sources = [
@ -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')

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
'use strict'
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
@ -40,6 +41,9 @@ module.exports = {
.openFile('examples/auctions')
.openFile('examples/auctions/blind_auction.vy')
},
// 'Add vyper file to run tests #group1': function (browser: NightwatchBrowser) {
// browser.addFile('TestBallot.sol', sources[0]['TestBallot.sol'])
// },
'Context menu click to compile blind_auction should succeed #group1': function (browser: NightwatchBrowser) {
browser
@ -176,3 +180,182 @@ def _createPokemon(_name: String[32], _dna: uint256, _HP: uint256):
wins: 0
})
self.totalPokemonCount += 1`
const blindAuction = `
# 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"]')

@ -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,12 +37,6 @@ 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'
@ -272,12 +266,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({
@ -351,12 +339,6 @@ class AppComponent {
ganacheProvider,
foundryProvider,
externalHttpProvider,
defaultInjectedProvider,
trustWalletInjectedProvider,
injected0ptimismProvider,
injectedArbitrumOneProvider,
injectedEphemeryTestnetProvider,
injectedSKALEChaosTestnetProvider,
this.walkthroughService,
search,
solidityumlgen,
@ -421,7 +403,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()
@ -528,6 +511,7 @@ class AppComponent {
await this.appManager.activatePlugin(['filePanel'])
// Set workspace after initial activation
this.appManager.on('editor', 'editorMounted', () => {
if (Array.isArray(this.workspace)) {

@ -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(
@ -92,7 +89,6 @@ export class SolCoder extends Plugin {
async code_explaining(prompt): 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(
@ -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")
}
}
}

@ -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,6 +18,10 @@ export class InjectedCustomProvider extends InjectedProviderDefaultBase {
}
async init() {
if (!this.chainId) {
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')

@ -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
}
}

@ -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"
}

@ -70,12 +70,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",

@ -2,6 +2,8 @@ import React from 'react' // eslint-disable-line
import {RunTabUI} from '@remix-ui/run-tab'
import {ViewPlugin} from '@remixproject/engine-web'
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 +30,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 +84,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) {
@ -150,29 +153,24 @@ 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 (event, name, 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(name, name, true, false, false)
}
if (window && window.trustwallet) {
const displayNameInjected = `Injected Provider - TrustWallet`
await addProvider('injected-trustwallet', displayNameInjected, true, false)
const registerInjectedProvider = async (event) => {
console.log('registerInjectedProvider', event)
await this.engine.register([new InjectedProviderDefault(event.detail.provider, event.detail.info.name)])
await addProvider(event.detail.info.name, event.detail.info.name, true, false, false)
await addCustomInjectedProvider(event, 'Optimism', '0xa', ['https://mainnet.optimism.io'])
await addCustomInjectedProvider(event, 'Arbitrum One', '0xa4b1', ['https://arb1.arbitrum.io/rpc'])
await addCustomInjectedProvider(event, 'SKALE Chaos Testnet', '0x50877ed6', ['https://staging-v3.skalenodes.com/v1/staging-fast-active-bellatrix'], {
"name": "sFUEL",
"symbol": "sFUEL",
"decimals": 18
})
await addCustomInjectedProvider(event, 'Ephemery Testnet', '', ['https://arb1.arbitrum.io/rpc'])
}
// VM
@ -191,8 +189,10 @@ export class RunTab extends ViewPlugin {
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)
*/
// external provider
await addProvider('basic-http-provider', 'Custom - External Http Provider', false, false)
@ -200,9 +200,16 @@ export class RunTab extends ViewPlugin {
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)
// register injected providers
window.addEventListener(
"eip6963:announceProvider",
(event) => {
registerInjectedProvider(event)
}
)
window.dispatchEvent(new Event("eip6963:requestProvider"))
}
writeFile(fileName, content) {

@ -47,6 +47,7 @@ const App = () => {
try {
await remixClient.loaded()
remixClient.onFileChange((name) => {
!name.endsWith('.vy') && remixClient.changeStatus({ key: 'none' })
setOutput({})
setContract(name)
})
@ -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>

@ -263,8 +263,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 +277,7 @@ export async function compileContract(contract: string, compilerUrl: string, set
status: 'failed',
message: e.message
}
remixClient.eventEmitter.emit('setOutput', errorGettingContract)
return
}
@ -293,7 +295,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 +310,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 +324,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})
}
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/ghaction-helper",
"version": "0.1.26",
"version": "0.1.27",
"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.33",
"@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.47",
"chai": "^4.3.7",
"ethers": "^5.7.2",
"web3": "^4.1.1"
},
"types": "./src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd"
"gitHead": "65197fceebd45f013aefed3c4a90277cee7f2962"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-analyzer",
"version": "0.5.55",
"version": "0.5.56",
"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.77",
"@remix-project/remix-lib": "^0.5.54",
"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": "65197fceebd45f013aefed3c4a90277cee7f2962",
"main": "./src/index.js"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-astwalker",
"version": "0.0.76",
"version": "0.0.77",
"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.54",
"@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": "65197fceebd45f013aefed3c4a90277cee7f2962",
"types": "./src/index.d.ts"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-debug",
"version": "0.5.46",
"version": "0.5.47",
"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.77",
"@remix-project/remix-lib": "^0.5.54",
"@remix-project/remix-simulator": "^0.2.47",
"@remix-project/remix-solidity": "^0.5.33",
"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": "65197fceebd45f013aefed3c4a90277cee7f2962",
"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.54",
"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": "65197fceebd45f013aefed3c4a90277cee7f2962",
"types": "./src/index.d.ts"
}

@ -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)

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-simulator",
"version": "0.2.46",
"version": "0.2.47",
"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.54",
"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": "65197fceebd45f013aefed3c4a90277cee7f2962",
"types": "./src/index.d.ts"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-solidity",
"version": "0.5.32",
"version": "0.5.33",
"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.54",
"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": "65197fceebd45f013aefed3c4a90277cee7f2962"
}

@ -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.47",
"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.54",
"@remix-project/remix-simulator": "^0.2.47",
"@remix-project/remix-solidity": "^0.5.33",
"@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": "65197fceebd45f013aefed3c4a90277cee7f2962"
}

@ -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

@ -9,7 +9,7 @@ export const SolidityState = ({calldata, message, className}) => {
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)'

@ -25,6 +25,10 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
if (context.selectedSuggestionInfo) {
return;
}
const getTextAtLine = (lineNumber) => {
const lineRange = model.getFullModelRange().setStartPosition(lineNumber, 1).setEndPosition(lineNumber + 1, 1);
return model.getValueInRange(lineRange);
}
// get text before the position of the completion
const word = model.getValueInRange({
startLineNumber: 1,
@ -33,6 +37,14 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
endColumn: position.column,
});
// get text after the position of the completion
const word_after = model.getValueInRange({
startLineNumber: position.lineNumber,
startColumn: position.column,
endLineNumber: model.getLineCount(),
endColumn: getTextAtLine(model.getLineCount()).length + 1,
});
if (!word.endsWith(' ') &&
!word.endsWith('.') &&
!word.endsWith('(')) {
@ -80,7 +92,6 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
return; // do not do completion on single and multiline comment
}
// abort if there is a signal
if (token.isCancellationRequested) {
return
@ -91,8 +102,34 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
return
}
if (word.replace(/ +$/, '').endsWith('\n')){
// Code insertion
try{
const output = await this.props.plugin.call('solcoder', 'code_insertion', word, word_after)
_paq.push(['trackEvent', 'ai', 'solcoder', 'code_insertion'])
const generatedText = output[0] // no need to clean it. should already be
const item: monacoTypes.languages.InlineCompletion = {
insertText: generatedText
};
this.completionEnabled = false
const handleCompletionTimer = new CompletionTimer(5000, () => { this.completionEnabled = true });
handleCompletionTimer.start()
return {
items: [item],
enableForwardStability: true
}
}
catch (err){
return
}
}
let result
try {
// Code completion
const output = await this.props.plugin.call('solcoder', 'code_completion', word)
_paq.push(['trackEvent', 'ai', 'solcoder', 'code_completion'])
const generatedText = output[0]

@ -1,5 +1,5 @@
import { ContractData } from "@remix-project/core-plugin"
import { addNewInstance, addNewSavedInstance, addProvider, clearAllInstances, clearAllSavedInstances, clearRecorderCount, hidePopUp, newProxyDeployment, removeExistingInstance, removeProvider, setBaseFeePerGas, setConfirmSettings, setCurrentContract, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setGasPrice, setGasPriceStatus, setMatchPassphrase, setMaxFee, setMaxPriorityFee, setNetworkName, setPassphrase, setPathToScenario, setSelectedAccount, setSendUnit, setSendValue } from "./payload"
import { addNewInstance, addNewPinnedInstance, addProvider, clearAllInstances, clearAllPinnedInstances, clearRecorderCount, hidePopUp, newProxyDeployment, removeExistingInstance, removeProvider, setBaseFeePerGas, setConfirmSettings, setCurrentContract, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setGasPrice, setGasPriceStatus, setMatchPassphrase, setMaxFee, setMaxPriorityFee, setNetworkName, setChainId, setPassphrase, setPathToScenario, setSelectedAccount, setSendUnit, setSendValue } from "./payload"
export const setAccount = (dispatch: React.Dispatch<any>, account: string) => {
dispatch(setSelectedAccount(account))
@ -21,6 +21,10 @@ export const setNetworkNameFromProvider = (dispatch: React.Dispatch<any>, networ
dispatch(setNetworkName(networkName))
}
export const setPinnedChainId = (dispatch: React.Dispatch<any>, chainId: string) => {
dispatch(setChainId(chainId))
}
export const addExternalProvider = (dispatch: React.Dispatch<any>, network) => {
dispatch(addProvider(network))
}
@ -70,13 +74,13 @@ export const addInstance = (dispatch: React.Dispatch<any>, instance: { contractD
dispatch(addNewInstance(instance))
}
export const addSavedInstance = (dispatch: React.Dispatch<any>, instance: { contractData?: ContractData, address: string, name: string, abi?: any, decodedResponse?: Record<number, any>, savedOn?: number, filePath?: string }) => {
export const addPinnedInstance = (dispatch: React.Dispatch<any>, instance: { contractData?: ContractData, address: string, name: string, abi?: any, decodedResponse?: Record<number, any>, pinnedAt?: number, filePath?: string }) => {
instance.decodedResponse = {}
dispatch(addNewSavedInstance(instance))
dispatch(addNewPinnedInstance(instance))
}
export const removeInstance = (dispatch: React.Dispatch<any>, index: number, isSavedContract: boolean, shouldDelete: boolean) => {
dispatch(removeExistingInstance(index, isSavedContract, shouldDelete))
export const removeInstance = (dispatch: React.Dispatch<any>, index: number, isPinnedContract: boolean, shouldDelete: boolean) => {
dispatch(removeExistingInstance(index, isPinnedContract, shouldDelete))
}
export const clearInstances = (dispatch: React.Dispatch<any>) => {
@ -84,8 +88,8 @@ export const clearInstances = (dispatch: React.Dispatch<any>) => {
dispatch(clearRecorderCount())
}
export const clearSavedInstances = (dispatch: React.Dispatch<any>) => {
dispatch(clearAllSavedInstances())
export const clearPinnedInstances = (dispatch: React.Dispatch<any>) => {
dispatch(clearAllPinnedInstances())
dispatch(clearRecorderCount())
}

@ -283,7 +283,7 @@ export const runTransactions = (
plugin: RunTab,
dispatch: React.Dispatch<any>,
instanceIndex: number,
isSavedContract: boolean,
isPinnedContract: boolean,
lookupOnly: boolean,
funcABI: FuncABI,
inputsValues: string,
@ -320,7 +320,7 @@ export const runTransactions = (
(returnValue) => {
const response = txFormat.decodeResponse(returnValue, funcABI)
dispatch(setDecodedResponse(instanceIndex, response, funcIndex, isSavedContract))
dispatch(setDecodedResponse(instanceIndex, response, funcIndex, isPinnedContract))
},
(network, tx, gasEstimation, continueTxExecution, cancelCb) => {
confirmationHandler(plugin, dispatch, mainnetPrompt, network, tx, gasEstimation, continueTxExecution, cancelCb)
@ -339,8 +339,9 @@ export const getFuncABIInputs = (plugin: RunTab, funcABI: FuncABI) => {
}
export const updateInstanceBalance = async (plugin: RunTab, dispatch: React.Dispatch<any>) => {
if (plugin.REACT_API?.instances?.instanceList?.length) {
const instances = plugin.REACT_API?.instances?.instanceList
if (plugin.REACT_API?.instances?.instanceList?.length || plugin.REACT_API?.pinnedInstances?.instanceList?.length) {
let instances = plugin.REACT_API?.instances?.instanceList?.length ? plugin.REACT_API?.instances?.instanceList : []
instances = plugin.REACT_API?.pinnedInstances?.instanceList.length ? instances.concat(plugin.REACT_API.pinnedInstances.instanceList) : instances
for (const instance of instances) {
const balInEth = await plugin.blockchain.getBalanceInEther(instance.address)
instance.balance = balInEth

@ -1,8 +1,8 @@
import { envChangeNotification } from "@remix-ui/helper"
import { RunTab } from "../types/run-tab"
import { setExecutionContext, setFinalContext, updateAccountBalances, fillAccountsList } from "./account"
import { addExternalProvider, addInstance, addSavedInstance, addNewProxyDeployment, removeExternalProvider, setNetworkNameFromProvider } from "./actions"
import { addDeployOption, clearAllInstances, clearAllSavedInstances, clearRecorderCount, fetchContractListSuccess, resetProxyDeployments, resetUdapp, setCurrentContract, setCurrentFile, setLoadType, setRecorderCount, setRemixDActivated, setSendValue, fetchAccountsListSuccess } from "./payload"
import { addExternalProvider, addInstance, addPinnedInstance, addNewProxyDeployment, removeExternalProvider, setNetworkNameFromProvider, setPinnedChainId } from "./actions"
import { addDeployOption, clearAllInstances, clearAllPinnedInstances, clearRecorderCount, fetchContractListSuccess, resetProxyDeployments, resetUdapp, setCurrentContract, setCurrentFile, setLoadType, setRecorderCount, setRemixDActivated, setSendValue, fetchAccountsListSuccess } from "./payload"
import { updateInstanceBalance } from './deploy'
import { CompilerAbstract } from '@remix-project/remix-solidity'
import BN from 'bn.js'
@ -33,9 +33,10 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
}
setFinalContext(plugin, dispatch)
fillAccountsList(plugin, dispatch)
await loadPinnedContracts(plugin, dispatch)
})
plugin.blockchain.event.register('networkStatus', ({ error, network }) => {
plugin.blockchain.event.register('networkStatus', async ({ error, network }) => {
if (error) {
const netUI = 'can\'t detect network'
setNetworkNameFromProvider(dispatch, netUI)
@ -44,8 +45,9 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
}
const networkProvider = plugin.networkModule.getNetworkProvider.bind(plugin.networkModule)
const netUI = !networkProvider().startsWith('vm') ? `${network.name} (${network.id || '-'}) network` : 'VM'
const pinnedChainId = !networkProvider().startsWith('vm') ? network.id : networkProvider()
setNetworkNameFromProvider(dispatch, netUI)
setPinnedChainId(dispatch, pinnedChainId)
})
plugin.blockchain.event.register('addProvider', provider => addExternalProvider(dispatch, provider))
@ -79,21 +81,22 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
dispatch(clearAllInstances())
})
plugin.on('udapp', 'clearAllSavedInstancesReducer', () => {
dispatch(clearAllSavedInstances())
plugin.on('udapp', 'clearAllPinnedInstancesReducer', () => {
dispatch(clearAllPinnedInstances())
})
plugin.on('udapp', 'addInstanceReducer', (address, abi, name, contractData?) => {
addInstance(dispatch, { contractData, abi, address, name })
})
plugin.on('udapp', 'addSavedInstanceReducer', (address, abi, name, savedOn, filePath) => {
addSavedInstance(dispatch, { abi, address, name, savedOn, filePath})
plugin.on('udapp', 'addPinnedInstanceReducer', (address, abi, name, pinnedAt, filePath) => {
addPinnedInstance(dispatch, { abi, address, name, pinnedAt, filePath})
})
plugin.on('filePanel', 'setWorkspace', () => {
plugin.on('filePanel', 'setWorkspace', async () => {
dispatch(resetUdapp())
resetAndInit(plugin)
await migrateSavedContracts(plugin)
plugin.call('manager', 'isActive', 'remixd').then((activated) => {
dispatch(setRemixDActivated(activated))
})
@ -163,6 +166,49 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
}, 30000)
}
const loadPinnedContracts = async (plugin, dispatch) => {
await plugin.call('udapp', 'clearAllPinnedInstances')
const { network } = await plugin.call('blockchain', 'getCurrentNetworkStatus')
const dirName = plugin.REACT_API.networkName === 'VM' ? plugin.REACT_API.selectExEnv : network.id
const isPinnedAvailable = await plugin.call('fileManager', 'exists', `.deploys/pinned-contracts/${dirName}`)
if (isPinnedAvailable) {
try {
const list = await plugin.call('fileManager', 'readdir', `.deploys/pinned-contracts/${dirName}`)
const filePaths = Object.keys(list)
for (const file of filePaths) {
const pinnedContract = await plugin.call('fileManager', 'readFile', file)
const pinnedContractObj = JSON.parse(pinnedContract)
if (pinnedContractObj) addPinnedInstance(dispatch, pinnedContractObj)
}
} catch(err) {
console.log(err)
}
}
}
const migrateSavedContracts = async (plugin) => {
// Move contract saved in localstorage to Remix FE
const allSavedContracts = localStorage.getItem('savedContracts')
if (allSavedContracts) {
const savedContracts = JSON.parse(allSavedContracts)
for (const networkId in savedContracts) {
if (savedContracts[networkId].length > 0) {
for (const contractDetails of savedContracts[networkId]) {
const objToSave = {
name: contractDetails.name,
address: contractDetails.address,
abi: contractDetails.abi || contractDetails.contractData.abi,
filePath: contractDetails.filePath,
pinnedAt: contractDetails.savedOn
}
await plugin.call('fileManager', 'writeFile', `.deploys/pinned-contracts/${networkId}/${contractDetails.address}.json`, JSON.stringify(objToSave, null, 2))
}
}
}
localStorage.removeItem('savedContracts')
}
}
const broadcastCompilationResult = async (compilerName: string, plugin: RunTab, dispatch: React.Dispatch<any>, file, source, languageVersion, data, input?) => {
_paq.push(['trackEvent', 'udapp', 'broadcastCompilationResult', compilerName])
// TODO check whether the tab is configured

@ -48,9 +48,9 @@ export const setGasPriceStatus = (status: boolean) => updateGasPriceStatus(dispa
export const setMaxFee = (fee: string) => updateMaxFee(dispatch, fee)
export const setMaxPriorityFee = (fee: string) => updateMaxPriorityFee(dispatch, fee)
export const removeInstances = () => clearInstances(dispatch)
export const removeSingleInstance = (index: number, isSavedContract: boolean, shouldDelete: boolean) => removeInstance(dispatch, index, isSavedContract, shouldDelete)
export const removeSingleInstance = (index: number, isPinnedContract: boolean, shouldDelete: boolean) => removeInstance(dispatch, index, isPinnedContract, shouldDelete)
export const getExecutionContext = () => getContext(plugin)
export const executeTransactions = (instanceIndex: number, isSavedContract: boolean, lookupOnly: boolean, funcABI: FuncABI, inputsValues: string, contractName: string, contractABI, contract, address, logMsg:string, mainnetPrompt: MainnetPrompt, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, funcIndex?: number) => runTransactions(plugin, dispatch, instanceIndex, isSavedContract, lookupOnly, funcABI, inputsValues, contractName, contractABI, contract, address, logMsg, mainnetPrompt, gasEstimationPrompt, passphrasePrompt, funcIndex)
export const executeTransactions = (instanceIndex: number, isPinnedContract: boolean, lookupOnly: boolean, funcABI: FuncABI, inputsValues: string, contractName: string, contractABI, contract, address, logMsg:string, mainnetPrompt: MainnetPrompt, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, funcIndex?: number) => runTransactions(plugin, dispatch, instanceIndex, isPinnedContract, lookupOnly, funcABI, inputsValues, contractName, contractABI, contract, address, logMsg, mainnetPrompt, gasEstimationPrompt, passphrasePrompt, funcIndex)
export const loadFromAddress = (contract: ContractData, address: string) => loadAddress(plugin, dispatch, contract, address)
export const storeNewScenario = async (prompt: (msg: string, defaultValue: string) => JSX.Element) => storeScenario(plugin, dispatch, prompt)
export const runScenario = (liveMode: boolean, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, confirmDialogContent: MainnetPrompt) => runCurrentScenario(liveMode, plugin, dispatch, gasEstimationPrompt, passphrasePrompt, confirmDialogContent)

@ -1,5 +1,5 @@
import { ContractData } from '@remix-project/core-plugin'
import { ADD_DEPLOY_OPTION, ADD_INSTANCE, ADD_SAVED_INSTANCE, UPDATE_INSTANCES_BALANCE, ADD_PROVIDER, CLEAR_INSTANCES, CLEAR_SAVED_INSTANCES, CLEAR_RECORDER_COUNT, DISPLAY_NOTIFICATION, DISPLAY_POPUP_MESSAGE, FETCH_ACCOUNTS_LIST_FAILED, FETCH_ACCOUNTS_LIST_REQUEST, FETCH_ACCOUNTS_LIST_SUCCESS, FETCH_CONTRACT_LIST_FAILED, FETCH_CONTRACT_LIST_REQUEST, FETCH_CONTRACT_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, REMOVE_DEPLOY_OPTION, REMOVE_INSTANCE, REMOVE_PROVIDER, RESET_STATE, SET_BASE_FEE_PER_GAS, SET_CONFIRM_SETTINGS, SET_CURRENT_CONTRACT, SET_CURRENT_FILE, SET_DECODED_RESPONSE, SET_DEPLOY_OPTIONS, SET_EXECUTION_ENVIRONMENT, SET_EXTERNAL_WEB3_ENDPOINT, SET_GAS_LIMIT, SET_GAS_PRICE, SET_GAS_PRICE_STATUS, SET_IPFS_CHECKED_STATE, SET_LOAD_TYPE, SET_MATCH_PASSPHRASE, SET_MAX_FEE, SET_MAX_PRIORITY_FEE, SET_NETWORK_NAME, SET_PASSPHRASE, SET_PATH_TO_SCENARIO, SET_PERSONAL_MODE, SET_RECORDER_COUNT, SET_SELECTED_ACCOUNT, SET_SEND_UNIT, SET_SEND_VALUE, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS, EXTRACT_COMPILER_VERSION } from '../constants'
import { ADD_DEPLOY_OPTION, ADD_INSTANCE, ADD_PINNED_INSTANCE, UPDATE_INSTANCES_BALANCE, ADD_PROVIDER, CLEAR_INSTANCES, CLEAR_PINNED_INSTANCES, CLEAR_RECORDER_COUNT, DISPLAY_NOTIFICATION, DISPLAY_POPUP_MESSAGE, FETCH_ACCOUNTS_LIST_FAILED, FETCH_ACCOUNTS_LIST_REQUEST, FETCH_ACCOUNTS_LIST_SUCCESS, FETCH_CONTRACT_LIST_FAILED, FETCH_CONTRACT_LIST_REQUEST, FETCH_CONTRACT_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, REMOVE_DEPLOY_OPTION, REMOVE_INSTANCE, REMOVE_PROVIDER, RESET_STATE, SET_BASE_FEE_PER_GAS, SET_CONFIRM_SETTINGS, SET_CURRENT_CONTRACT, SET_CURRENT_FILE, SET_DECODED_RESPONSE, SET_DEPLOY_OPTIONS, SET_EXECUTION_ENVIRONMENT, SET_CHAIN_ID, SET_EXTERNAL_WEB3_ENDPOINT, SET_GAS_LIMIT, SET_GAS_PRICE, SET_GAS_PRICE_STATUS, SET_IPFS_CHECKED_STATE, SET_LOAD_TYPE, SET_MATCH_PASSPHRASE, SET_MAX_FEE, SET_MAX_PRIORITY_FEE, SET_NETWORK_NAME, SET_PASSPHRASE, SET_PATH_TO_SCENARIO, SET_PERSONAL_MODE, SET_RECORDER_COUNT, SET_SELECTED_ACCOUNT, SET_SEND_UNIT, SET_SEND_VALUE, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS, EXTRACT_COMPILER_VERSION } from '../constants'
import { ContractList, DeployOptions } from '../types'
export const fetchAccountsListRequest = () => {
@ -72,6 +72,13 @@ export const setNetworkName = (networkName: string) => {
}
}
export const setChainId = (chainId: string) => {
return {
type: SET_CHAIN_ID,
payload: chainId
}
}
export const addProvider = (provider: string) => {
return {
type: ADD_PROVIDER,
@ -230,19 +237,19 @@ export const addNewInstance = (instance: { contractData?: ContractData, address:
}
}
export const addNewSavedInstance = (instance: { contractData?: ContractData, address: string, name: string, abi?: any, savedOn?: number }) => {
export const addNewPinnedInstance = (instance: { contractData?: ContractData, address: string, name: string, abi?: any, pinnedAt?: number }) => {
return {
type: ADD_SAVED_INSTANCE,
type: ADD_PINNED_INSTANCE,
payload: instance
}
}
export const removeExistingInstance = (index: number, isSavedContract: boolean, shouldDelete: boolean) => {
export const removeExistingInstance = (index: number, isPinnedContract: boolean, shouldDelete: boolean) => {
return {
type: REMOVE_INSTANCE,
payload: {
index,
isSavedContract,
isPinnedContract,
shouldDelete
}
}
@ -254,20 +261,20 @@ export const clearAllInstances = () => {
}
}
export const clearAllSavedInstances = () => {
export const clearAllPinnedInstances = () => {
return {
type: CLEAR_SAVED_INSTANCES
type: CLEAR_PINNED_INSTANCES
}
}
export const setDecodedResponse = (instanceIndex: number, response, funcIndex?: number, isSavedContract?: boolean) => {
export const setDecodedResponse = (instanceIndex: number, response, funcIndex?: number, isPinnedContract?: boolean) => {
return {
type: SET_DECODED_RESPONSE,
payload: {
instanceIndex,
funcIndex,
response,
isSavedContract
isPinnedContract
}
}
}

@ -34,6 +34,13 @@ export function AccountUI(props: AccountProps) {
})
break
case 'vm-cancun':
setPlusOpt({
classList: '',
title: intl.formatMessage({id: 'udapp.createNewAccount'})
})
break
case 'vm-paris':
setPlusOpt({
classList: '',

@ -7,57 +7,6 @@ import { UniversalDappUI } from './universalDappUI'
export function InstanceContainerUI(props: InstanceContainerProps) {
const { instanceList } = props.instances
const enableSave = useRef(false)
const chainId = useRef()
useEffect(() => {
const fetchSavedContracts = async () => {
if (props.plugin.REACT_API.selectExEnv && props.plugin.REACT_API.selectExEnv.startsWith('vm-')) enableSave.current = false
else enableSave.current = true
if (enableSave.current) {
const { network } = await props.plugin.call('blockchain', 'getCurrentNetworkStatus')
chainId.current = network.id
// Move contract saved in localstorage to Remix FE
const allSavedContracts = localStorage.getItem('savedContracts')
if (allSavedContracts) {
const savedContracts = JSON.parse(allSavedContracts)
for (const networkId in savedContracts) {
if (savedContracts[networkId].length > 0) {
for (const contractDetails of savedContracts[networkId]) {
const objToSave = {
name: contractDetails.name,
address: contractDetails.address,
abi: contractDetails.abi || contractDetails.contractData.abi,
filePath: contractDetails.filePath,
pinnedAt: contractDetails.savedOn
}
await props.plugin.call('fileManager', 'writeFile', `.deploys/pinned-contracts/${networkId}/${contractDetails.address}.json`, JSON.stringify(objToSave, null, 2))
}
}
}
localStorage.removeItem('savedContracts')
}
// Clear existing saved instance state
await props.plugin.call('udapp', 'clearAllSavedInstances')
// Load contracts from FE
const isPinnedAvailable = await props.plugin.call('fileManager', 'exists', `.deploys/pinned-contracts/${chainId.current}`)
if (isPinnedAvailable) {
try {
const list = await props.plugin.call('fileManager', 'readdir', `.deploys/pinned-contracts/${chainId.current}`)
const filePaths = Object.keys(list)
for (const file of filePaths) {
const pinnedContract = await props.plugin.call('fileManager', 'readFile', file)
const pinnedContractObj = JSON.parse(pinnedContract)
if (pinnedContractObj) await props.plugin.call('udapp', 'addSavedInstance', pinnedContractObj.address, pinnedContractObj.abi, pinnedContractObj.name, pinnedContractObj.pinnedAt, pinnedContractObj.filePath)
}
} catch(err) {
console.log(err)
}
}
}
}
fetchSavedContracts()
}, [props.plugin.REACT_API.selectExEnv, props.plugin.REACT_API.networkName])
const clearInstance = () => {
props.clearInstances()
@ -65,51 +14,49 @@ export function InstanceContainerUI(props: InstanceContainerProps) {
return (
<div className="udapp_instanceContainer mt-3 border-0 list-group-item">
{ enableSave.current ? (
<div className="d-flex justify-content-between align-items-center pl-2">
<CustomTooltip placement="top-start" tooltipClasses="text-nowrap" tooltipId="deployAndRunPinnedContractsTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextPinnedContracts" />}>
<label className="udapp_deployedContracts">
<FormattedMessage id="udapp.savedContracts" />
<span style={{fontSize: '0.75rem'}}> (chain id: {chainId.current})</span>
</label>
</CustomTooltip>
</div>) : null }
{ enableSave.current ? (
props.savedInstances.instanceList.length > 0 ? (
<div>
{' '}
{props.savedInstances.instanceList.map((instance, index) => {
return (
<UniversalDappUI
key={index}
instance={instance}
isSavedContract={true}
context={props.getContext()}
removeInstance={props.removeInstance}
index={index}
gasEstimationPrompt={props.gasEstimationPrompt}
passphrasePrompt={props.passphrasePrompt}
mainnetPrompt={props.mainnetPrompt}
runTransactions={props.runTransactions}
sendValue={props.sendValue}
getFuncABIInputs={props.getFuncABIInputs}
plugin={props.plugin}
exEnvironment={props.exEnvironment}
editInstance={props.editInstance}
/>
)
})}
</div>
) : (
<span className="mx-2 mt-2 text-dark" data-id="NoSavedInstanceText">
<FormattedMessage id="udapp.NoSavedInstanceText" />
</span>
)
) : null }
<div className="d-flex justify-content-between align-items-center pl-2">
<CustomTooltip placement="top-start" tooltipClasses="text-nowrap" tooltipId="deployAndRunPinnedContractsTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextPinnedContracts" />}>
<label className="udapp_deployedContracts" data-id="pinnedContracts">
<FormattedMessage id="udapp.pinnedContracts" />
<span style={{fontSize: '0.75rem'}} data-id="pinnedContractsSublabel"> (network: {props.plugin.REACT_API.chainId}) </span>
</label>
</CustomTooltip>
</div>
{props.pinnedInstances.instanceList.length > 0 ? (
<div>
{' '}
{props.pinnedInstances.instanceList.map((instance, index) => {
return (
<UniversalDappUI
key={index}
instance={instance}
isPinnedContract={true}
context={props.getContext()}
removeInstance={props.removeInstance}
index={index}
gasEstimationPrompt={props.gasEstimationPrompt}
passphrasePrompt={props.passphrasePrompt}
mainnetPrompt={props.mainnetPrompt}
runTransactions={props.runTransactions}
sendValue={props.sendValue}
getFuncABIInputs={props.getFuncABIInputs}
plugin={props.plugin}
exEnvironment={props.exEnvironment}
editInstance={props.editInstance}
/>
)
})}
</div>
) : (
<span className="mx-2 mt-3 alert alert-secondary" data-id="NoPinnedInstanceText">
<FormattedMessage id="udapp.NoPinnedInstanceText" />
</span>
)}
<div className="d-flex justify-content-between align-items-center pl-2 mb-2 mt-2">
<CustomTooltip placement="top-start" tooltipClasses="text-nowrap" tooltipId="deployAndRunClearInstancesTooltip" tooltipText={<FormattedMessage id="udapp.tooltipText6" />}>
<label className="udapp_deployedContracts">
<label className="udapp_deployedContracts" data-id="unpinnedContracts">
<FormattedMessage id="udapp.deployedContracts" />
</label>
</CustomTooltip>
@ -120,7 +67,7 @@ export function InstanceContainerUI(props: InstanceContainerProps) {
tooltipId="deployAndRunClearInstancesTooltip"
tooltipText={<FormattedMessage id="udapp.deployAndRunClearInstances" />}
>
<i className="mr-1 udapp_icon far fa-trash-alt" data-id="deployAndRunClearInstances" onClick={clearInstance} aria-hidden="true"></i>
<i className="mr-1 p-2 udapp_icon far fa-trash-alt" data-id="deployAndRunClearInstances" onClick={clearInstance} aria-hidden="true"></i>
</CustomTooltip>
) : null}
</div>
@ -132,7 +79,7 @@ export function InstanceContainerUI(props: InstanceContainerProps) {
<UniversalDappUI
key={index}
instance={instance}
isSavedContract={false}
isPinnedContract={false}
context={props.getContext()}
removeInstance={props.removeInstance}
index={index}
@ -150,7 +97,7 @@ export function InstanceContainerUI(props: InstanceContainerProps) {
})}
</div>
) : (
<span className="mx-2 mt-3 alert alert-warning" data-id="deployAndRunNoInstanceText" role="alert">
<span className="mx-2 mt-3 alert alert-secondary" data-id="deployAndRunNoInstanceText" role="alert">
<FormattedMessage id="udapp.deployAndRunNoInstanceText" />
</span>
)}

@ -113,27 +113,25 @@ export function UniversalDappUI(props: UdappProps) {
}
const unsavePinnedContract = async () => {
const {network} = await props.plugin.call('blockchain', 'getCurrentNetworkStatus')
await props.plugin.call('fileManager', 'remove', `.deploys/pinned-contracts/${network.id}/${props.instance.address}.json`)
await props.plugin.call('fileManager', 'remove', `.deploys/pinned-contracts/${props.plugin.REACT_API.chainId}/${props.instance.address}.json`)
}
const remove = async() => {
if (props.isSavedContract) {
if (props.isPinnedContract) {
await unsavePinnedContract()
_paq.push(['trackEvent', 'udapp', 'pinContracts', 'unpinned'])
}
props.removeInstance(props.index, props.isSavedContract, false)
props.removeInstance(props.index, props.isPinnedContract, false)
}
const deletePinnedContract = async() => {
await unsavePinnedContract()
_paq.push(['trackEvent', 'udapp', 'pinContracts', 'deletePinned'])
props.removeInstance(props.index, props.isSavedContract, true)
props.removeInstance(props.index, props.isPinnedContract, true)
}
const pinContract = async() => {
const workspace = await props.plugin.call('filePanel', 'getCurrentWorkspace')
const {network} = await props.plugin.call('blockchain', 'getCurrentNetworkStatus')
const objToSave = {
name: props.instance.name,
address: props.instance.address,
@ -141,21 +139,22 @@ export function UniversalDappUI(props: UdappProps) {
filePath: props.instance.filePath || `${workspace.name}/${props.instance.contractData.contract.file}`,
pinnedAt: Date.now()
}
await props.plugin.call('fileManager', 'writeFile', `.deploys/pinned-contracts/${network.id}/${props.instance.address}.json`, JSON.stringify(objToSave, null, 2))
await props.plugin.call('fileManager', 'writeFile', `.deploys/pinned-contracts/${props.plugin.REACT_API.chainId}/${props.instance.address}.json`, JSON.stringify(objToSave, null, 2))
// Add contract to saved contracts list on UI
await props.plugin.call('udapp', 'addSavedInstance', objToSave.address, objToSave.abi, objToSave.name, objToSave.pinnedAt, objToSave.filePath)
_paq.push(['trackEvent', 'udapp', 'pinContracts', `pinned at ${network.id}`])
await props.plugin.call('udapp', 'addPinnedInstance', objToSave.address, objToSave.abi, objToSave.name, objToSave.pinnedAt, objToSave.filePath)
_paq.push(['trackEvent', 'udapp', 'pinContracts', `pinned at ${props.plugin.REACT_API.chainId}`])
// Remove contract from deployed contracts list on UI
props.removeInstance(props.index, false, false)
}
const runTransaction = (lookupOnly, funcABI: FuncABI, valArr, inputsValues, funcIndex?: number) => {
if (props.isPinnedContract) _paq.push(['trackEvent', 'udapp', 'pinContracts', 'interactWithPinned'])
const functionName = funcABI.type === 'function' ? funcABI.name : `(${funcABI.type})`
const logMsg = `${lookupOnly ? 'call' : 'transact'} to ${props.instance.name}.${functionName}`
props.runTransactions(
props.index,
props.isSavedContract,
props.isPinnedContract,
lookupOnly,
funcABI,
inputsValues,
@ -251,6 +250,7 @@ export function UniversalDappUI(props: UdappProps) {
className={`instance udapp_instance udapp_run-instance border-dark ${toggleExpander ? 'udapp_hidesub' : 'bg-light'}`}
id={`instance${address}`}
data-shared="universalDappUiInstance"
data-id={props.isPinnedContract ? `pinnedInstance${address}` : `unpinnedInstance${address}`}
>
<div className="udapp_title pb-0 alert alert-secondary">
<span data-id={`universalDappUiTitleExpander${props.index}`} className="btn udapp_titleExpander" onClick={toggleClass} style={{padding: "0.45rem"}}>
@ -258,7 +258,7 @@ export function UniversalDappUI(props: UdappProps) {
</span>
<div className="input-group udapp_nameNbuts">
<div className="udapp_titleText input-group-prepend">
{ props.isSavedContract ? ( <CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappUnpinTooltip" tooltipText={props.isSavedContract ? `Contract: ${props.instance.name}, Address: ${address}, Pinned at: ${new Date(props.instance.savedOn).toLocaleString()}` : '' }>
{ props.isPinnedContract ? ( <CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappUnpinTooltip" tooltipText={props.isPinnedContract ? `Contract: ${props.instance.name}, Address: ${address}, Pinned at: ${new Date(props.instance.pinnedAt).toLocaleString()}` : '' }>
<span className="input-group-text udapp_spanTitleText">
{props.instance.name} at {shortenAddress(address)}
</span>
@ -269,19 +269,18 @@ export function UniversalDappUI(props: UdappProps) {
<div className="btn" style={{padding: '0.15rem'}}>
<CopyToClipboard tip={intl.formatMessage({id: 'udapp.copy'})} content={address} direction={'top'} />
</div>
{ !(props.plugin.REACT_API.selectExEnv && props.plugin.REACT_API.selectExEnv.startsWith('vm-')) ?
props.isSavedContract ? ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappUnpinTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextUnpin" />}>
<i className="fas fa-thumbtack p-2 text-success" aria-hidden="true" data-id="universalDappUiUdappUnpin" onClick={remove}></i>
</CustomTooltip>
</div> ) : ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappPinTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextPin" />}>
<i className="far fa-thumbtack p-2" aria-hidden="true" data-id="universalDappUiUdappPin" onClick={pinContract}></i>
</CustomTooltip>
</div> )
: null}
{ props.isPinnedContract ? ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappUnpinTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextUnpin" />}>
<i className="fas fa-thumbtack p-2" aria-hidden="true" data-id="universalDappUiUdappUnpin" onClick={remove}></i>
</CustomTooltip>
</div> ) : ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappPinTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextPin" />}>
<i className="far fa-thumbtack p-2" aria-hidden="true" data-id="universalDappUiUdappPin" onClick={pinContract}></i>
</CustomTooltip>
</div> )
}
</div>
{ props.isSavedContract ? ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
{ props.isPinnedContract ? ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappDeleteTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextDelete" />}>
<i className="far fa-trash p-2" aria-hidden="true" data-id="universalDappUiUdappDelete" onClick={deletePinnedContract}></i>
</CustomTooltip>
@ -300,15 +299,15 @@ export function UniversalDappUI(props: UdappProps) {
</label>
{props.exEnvironment === 'injected' && <i className="fas fa-edit btn btn-sm p-0" onClick={() => {props.editInstance(props.instance)}}></i>}
</div>
{ props.isSavedContract && props.instance.savedOn ? (
<div className="d-flex" data-id="instanceContractSavedOn">
{ props.isPinnedContract && props.instance.pinnedAt ? (
<div className="d-flex" data-id="instanceContractPinnedAt">
<label>
<b><FormattedMessage id="udapp.savedOn" />:</b> {(new Date(props.instance.savedOn)).toLocaleString()}
<b><FormattedMessage id="udapp.pinnedAt" />:</b> {(new Date(props.instance.pinnedAt)).toLocaleString()}
</label>
</div>
) : null }
{ props.isSavedContract && props.instance.filePath ? (
<div className="d-flex" data-id="instanceContractFilePath">
{ props.isPinnedContract && props.instance.filePath ? (
<div className="d-flex" data-id="instanceContractFilePath" style={{textAlign: "start", lineBreak: "anywhere"}}>
<label>
<b><FormattedMessage id="udapp.filePath" />:</b> {props.instance.filePath}
</label>

@ -33,11 +33,11 @@ export const SET_MAX_PRIORITY_FEE = 'SET_MAX_PRIORITY_FEE'
export const SET_BASE_FEE_PER_GAS = 'SET_BASE_FEE_PER_GAS'
export const SET_GAS_PRICE = 'SET_GAS_PRICE'
export const ADD_INSTANCE = 'ADD_INSTANCE'
export const ADD_SAVED_INSTANCE = 'ADD_SAVED_INSTANCE'
export const ADD_PINNED_INSTANCE = 'ADD_PINNED_INSTANCE'
export const UPDATE_INSTANCES_BALANCE = 'UPDATE_INSTANCES_BALANCE'
export const REMOVE_INSTANCE = 'REMOVE_INSTANCE'
export const CLEAR_INSTANCES = 'CLEAR_INSTANCES'
export const CLEAR_SAVED_INSTANCES = 'CLEAR_SAVED_INSTANCES'
export const CLEAR_PINNED_INSTANCES = 'CLEAR_PINNED_INSTANCES'
export const SET_DECODED_RESPONSE = 'SET_DECODED_RESPONSE'
export const SET_PATH_TO_SCENARIO = 'SET_PATH_TO_SCENARIO'
export const SET_RECORDER_COUNT = 'SET_RECORDER_COUNT'
@ -52,3 +52,4 @@ export const FETCH_PROXY_DEPLOYMENTS = 'FETCH_PROXY_DEPLOYMENTS'
export const NEW_PROXY_DEPLOYMENT = 'NEW_PROXY_DEPLOYMENT'
export const RESET_PROXY_DEPLOYMENTS = 'RESET_PROXY_DEPLOYMENTS'
export const EXTRACT_COMPILER_VERSION = 'EXTRACT_COMPILER_VERSION'
export const SET_CHAIN_ID = 'SET_CHAIN_ID'

@ -1,6 +1,6 @@
import { ContractData } from '@remix-project/core-plugin'
import { ContractList, DeployOptions, RunTabState } from '../types'
import { ADD_INSTANCE, ADD_SAVED_INSTANCE, UPDATE_INSTANCES_BALANCE, ADD_PROVIDER, CLEAR_INSTANCES, CLEAR_SAVED_INSTANCES, CLEAR_RECORDER_COUNT, DISPLAY_NOTIFICATION, DISPLAY_POPUP_MESSAGE, FETCH_ACCOUNTS_LIST_FAILED, FETCH_ACCOUNTS_LIST_REQUEST, FETCH_ACCOUNTS_LIST_SUCCESS, FETCH_CONTRACT_LIST_FAILED, FETCH_CONTRACT_LIST_REQUEST, FETCH_CONTRACT_LIST_SUCCESS, FETCH_PROVIDER_LIST_FAILED, FETCH_PROVIDER_LIST_REQUEST, FETCH_PROVIDER_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, REMOVE_INSTANCE, REMOVE_PROVIDER, RESET_STATE, SET_BASE_FEE_PER_GAS, SET_CONFIRM_SETTINGS, SET_CURRENT_CONTRACT, SET_CURRENT_FILE, SET_DECODED_RESPONSE, SET_DEPLOY_OPTIONS, SET_EXECUTION_ENVIRONMENT, SET_EXTERNAL_WEB3_ENDPOINT, SET_GAS_LIMIT, SET_GAS_PRICE, SET_GAS_PRICE_STATUS, SET_IPFS_CHECKED_STATE, SET_LOAD_TYPE, SET_MATCH_PASSPHRASE, SET_MAX_FEE, SET_MAX_PRIORITY_FEE, SET_NETWORK_NAME, SET_PASSPHRASE, SET_PATH_TO_SCENARIO, SET_PERSONAL_MODE, SET_RECORDER_COUNT, SET_SELECTED_ACCOUNT, SET_SEND_UNIT, SET_SEND_VALUE, ADD_DEPLOY_OPTION, REMOVE_DEPLOY_OPTION, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS, EXTRACT_COMPILER_VERSION } from '../constants'
import { ADD_INSTANCE, ADD_PINNED_INSTANCE, UPDATE_INSTANCES_BALANCE, ADD_PROVIDER, CLEAR_INSTANCES, CLEAR_PINNED_INSTANCES, CLEAR_RECORDER_COUNT, DISPLAY_NOTIFICATION, DISPLAY_POPUP_MESSAGE, FETCH_ACCOUNTS_LIST_FAILED, FETCH_ACCOUNTS_LIST_REQUEST, FETCH_ACCOUNTS_LIST_SUCCESS, FETCH_CONTRACT_LIST_FAILED, FETCH_CONTRACT_LIST_REQUEST, FETCH_CONTRACT_LIST_SUCCESS, FETCH_PROVIDER_LIST_FAILED, FETCH_PROVIDER_LIST_REQUEST, FETCH_PROVIDER_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, REMOVE_INSTANCE, REMOVE_PROVIDER, RESET_STATE, SET_BASE_FEE_PER_GAS, SET_CONFIRM_SETTINGS, SET_CHAIN_ID, SET_CURRENT_CONTRACT, SET_CURRENT_FILE, SET_DECODED_RESPONSE, SET_DEPLOY_OPTIONS, SET_EXECUTION_ENVIRONMENT, SET_EXTERNAL_WEB3_ENDPOINT, SET_GAS_LIMIT, SET_GAS_PRICE, SET_GAS_PRICE_STATUS, SET_IPFS_CHECKED_STATE, SET_LOAD_TYPE, SET_MATCH_PASSPHRASE, SET_MAX_FEE, SET_MAX_PRIORITY_FEE, SET_NETWORK_NAME, SET_PASSPHRASE, SET_PATH_TO_SCENARIO, SET_PERSONAL_MODE, SET_RECORDER_COUNT, SET_SELECTED_ACCOUNT, SET_SEND_UNIT, SET_SEND_VALUE, ADD_DEPLOY_OPTION, REMOVE_DEPLOY_OPTION, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS, EXTRACT_COMPILER_VERSION } from '../constants'
declare const window: any
interface Action {
@ -22,6 +22,7 @@ export const runTabInitialState: RunTabState = {
selectExEnv: 'vm-paris',
personalMode: false,
networkName: 'VM',
chainId:'-',
providers: {
providerList: [],
isRequesting: false,
@ -63,7 +64,7 @@ export const runTabInitialState: RunTabState = {
instanceList: [],
error: null
},
savedInstances: {
pinnedInstances: {
instanceList: [],
error: null
},
@ -196,7 +197,16 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
return {
...state,
networkName: payload
networkName: payload,
}
}
case SET_CHAIN_ID: {
const payload = action.payload
return {
...state,
chainId: payload
}
}
@ -491,13 +501,13 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
}
}
case ADD_SAVED_INSTANCE: {
const payload: { contractData: ContractData, address: string, name: string, abi?: any, savedOn: number, decodedResponse?: Record<number, any> } = action.payload
case ADD_PINNED_INSTANCE: {
const payload: { contractData: ContractData, address: string, name: string, abi?: any, pinnedAt: number, decodedResponse?: Record<number, any> } = action.payload
return {
...state,
savedInstances: {
...state.savedInstances,
instanceList: [...state.savedInstances.instanceList, payload]
pinnedInstances: {
...state.pinnedInstances,
instanceList: [...state.pinnedInstances.instanceList, payload]
}
}
}
@ -515,25 +525,25 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
}
case REMOVE_INSTANCE: {
const payload: { index: number, isSavedContract: boolean, shouldDelete: boolean } = action.payload
const payload: { index: number, isPinnedContract: boolean, shouldDelete: boolean } = action.payload
if (payload.isSavedContract) {
if (payload.isPinnedContract) {
if (payload.shouldDelete) return {
...state,
savedInstances: {
...state.savedInstances,
instanceList: state.savedInstances.instanceList.filter((_, index) => index !== payload.index)
pinnedInstances: {
...state.pinnedInstances,
instanceList: state.pinnedInstances.instanceList.filter((_, index) => index !== payload.index)
}
}
else return {
...state,
savedInstances: {
...state.savedInstances,
instanceList: state.savedInstances.instanceList.filter((_, index) => index !== payload.index)
pinnedInstances: {
...state.pinnedInstances,
instanceList: state.pinnedInstances.instanceList.filter((_, index) => index !== payload.index)
},
instances: {
...state.instances,
instanceList: [...state.instances.instanceList, state.savedInstances.instanceList[payload.index]]
instanceList: [...state.instances.instanceList, state.pinnedInstances.instanceList[payload.index]]
}
}
} else return {
@ -555,10 +565,10 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
}
}
case CLEAR_SAVED_INSTANCES: {
case CLEAR_PINNED_INSTANCES: {
return {
...state,
savedInstances: {
pinnedInstances: {
instanceList: [],
error: null
}
@ -566,13 +576,13 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
}
case SET_DECODED_RESPONSE: {
const payload: { instanceIndex: number, funcIndex: number, response: any, isSavedContract: boolean } = action.payload
if (action.payload.isSavedContract)
const payload: { instanceIndex: number, funcIndex: number, response: any, isPinnedContract: boolean } = action.payload
if (action.payload.isPinnedContract)
return {
...state,
savedInstances: {
...state.savedInstances,
instanceList: state.savedInstances.instanceList.map((instance, index) => {
pinnedInstances: {
...state.pinnedInstances,
instanceList: state.pinnedInstances.instanceList.map((instance, index) => {
if (payload.instanceIndex === index) instance.decodedResponse[payload.funcIndex] = payload.response
return instance
})

@ -251,7 +251,7 @@ export function RunTabUI(props: RunTabProps) {
return (
<Fragment>
<div className="udapp_runTabView run-tab" id="runTabView" data-id="runTabView">
<div className="list-group list-group-flush">
<div className="list-group pb-4 list-group-flush">
<SettingsUI
networkName={runTab.networkName}
personalMode={runTab.personalMode}
@ -314,7 +314,7 @@ export function RunTabUI(props: RunTabProps) {
<InstanceContainerUI
plugin={plugin}
instances={runTab.instances}
savedInstances={runTab.savedInstances}
pinnedInstances={runTab.pinnedInstances}
clearInstances={removeInstances}
removeInstance={removeSingleInstance}
getContext={getExecutionContext}

@ -33,6 +33,7 @@ export interface RunTabState {
selectExEnv: string,
personalMode: boolean,
networkName: string,
chainId: string
providers: {
providerList: {
id?: string,
@ -96,7 +97,7 @@ export interface RunTabState {
}[],
error: string
},
savedInstances: {
pinnedInstances: {
instanceList: {
contractData?: ContractData,
address: string,
@ -104,7 +105,7 @@ export interface RunTabState {
name: string,
decodedResponse?: Record<number, any>,
abi?: any,
savedOn?: number
pinnedAt?: number
}[],
error: string
},
@ -307,7 +308,7 @@ export interface InstanceContainerProps {
}[],
error: string
},
savedInstances: {
pinnedInstances: {
instanceList: {
contractData?: ContractData,
address: string,
@ -315,17 +316,17 @@ export interface InstanceContainerProps {
name: string,
decodedResponse?: Record<number, any>,
abi?: any,
savedOn?: number,
pinnedAt?: number,
filePath?: string
}[],
error: string
},
clearInstances: () => void,
removeInstance: (index: number, isSavedContract:boolean, shouldDelete: boolean) => void,
removeInstance: (index: number, isPinnedContract:boolean, shouldDelete: boolean) => void,
getContext: () => 'memory' | 'blockchain',
runTransactions: (
instanceIndex: number,
isSavedContract: boolean,
isPinnedContract: boolean,
lookupOnly: boolean,
funcABI: FuncABI,
inputsValues: string,
@ -425,19 +426,19 @@ export interface UdappProps {
name: string,
decodedResponse?: Record<number, any>,
abi?: any,
savedOn?: number,
pinnedAt?: number,
filePath?: string
},
context: 'memory' | 'blockchain',
isSavedContract?: boolean
removeInstance: (index: number, isSavedContract: boolean, shouldDelete: boolean) => void,
isPinnedContract?: boolean
removeInstance: (index: number, isPinnedContract: boolean, shouldDelete: boolean) => void,
index: number,
gasEstimationPrompt: (msg: string) => JSX.Element,
passphrasePrompt: (message: string) => JSX.Element,
mainnetPrompt: (tx: Tx, network: Network, amount: string, gasEstimation: string, gasFees: (maxFee: string, cb: (txFeeText: string, priceStatus: boolean) => void) => void, determineGasPrice: (cb: (txFeeText: string, gasPriceValue: string, gasPriceStatus: boolean) => void) => void) => JSX.Element,
runTransactions: (
instanceIndex: number,
isSavedContract: boolean,
isPinnedContract: boolean,
lookupOnly: boolean,
funcABI: FuncABI,
inputsValues: string,

@ -138,7 +138,7 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
const onchangeCopilotActivate = () => {
if (!props.useCopilot) {
copilotActivate(props.config, props.useCopilot, dispatch)
props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `Solidity copilot deactivated!` })
props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `Solidity copilot not activated!` })
return
}

@ -287,10 +287,10 @@ export const TabsUI = (props: TabsUIProps) => {
<span
data-id="remix_ai_docs"
id="remix_ai_docs"
className="btn ai-docs"
className="btn pl-2 pr-0 py-0 d-flex ai-docs"
role='link'
onClick={()=>{
window.open("https://remix-ide.readthedocs.io/en/latest/security.html")
window.open("https://remix-ide.readthedocs.io/en/latest/ai.html")
_paq.push(['trackEvent', 'ai', 'solcoder', 'documentation'])
}}
>

@ -299,7 +299,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
}
return Object.keys(standardInput.sources)[0]
} else {
// preserve JSON whitepsace if this isn't a Solidity compiler JSON-input-output file
// preserve JSON whitespace if this isn't a Solidity compiler JSON-input-output file
content = data.content
await workspaceProvider.set(path, content)
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-url-resolver",
"version": "0.0.75",
"version": "0.0.76",
"description": "Solidity import url resolver engine",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -41,5 +41,5 @@
"typescript": "^3.1.6"
},
"typings": "src/index.d.ts",
"gitHead": "b6fdc61a09e0b748d0034aee789916e79ec73bfd"
"gitHead": "65197fceebd45f013aefed3c4a90277cee7f2962"
}

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

@ -7,21 +7,21 @@ The workspace comprises two main directories:
### circuits: Contains sample Hash Checker contracts. These can be compiled to generate a witness using 'Circom ZKP Compiler' plugin.
### scripts: Provides a sample script designed for a trusted setup using snarkjs. This script also aids in generating Solidity code, which is essential for on-chain deployment.
### scripts: Provides a sample script designed for a trusted setup using snarkjs. This script also aids in generating Solidity code, which is essential for on-chain deployment. There have 2 scripts options to choose from, Groth16 and Plonk.
### first steps:
#### 1) compile the hash checker circuit using the remix circom compiler. This will generate artifacts.
#### 2) execute the file `run_setup.ts`:
#### 2) execute the file `groth16_trusted_setup.ts` found in `scripts/groth16` directory:
This step generate a verification key that can be used for generating proof, it will also generate a Solidity contract for on-chain verification.
Note that this section should only be used for development purposes as this way of running the setup is heavily centralized (although some pieces of this script can be used to achieve that).
This generates a verification key (`./zk/build/verification_key.json`) and artifacts from the setup (`./zk/build/zk_setup.txt`).
This generates a verification key (`./zk/build/groth16/verification_key.json`) and a key for proof generation (`./zk/build/groth16/zkey_final.txt`).
#### 3) execute the file `run_verification.ts`:
#### 3) execute the file `groth16_zkproof.ts` found in `scripts/groth16`:
This script:
@ -33,3 +33,5 @@ This script:
The witness will be generated only if the provided hash is the poseidon hash of these 4 values.
- verify that the proof is valid `(snarkjs.groth16.verify)`
#### The steps above for groth16 scripts apply also to plonk scripts.

@ -3,12 +3,18 @@ export default async () => {
// @ts-ignore
'circuits/calculate_hash.circom': (await import('raw-loader!./circuits/calculate_hash.circom')).default,
// @ts-ignore
'scripts/run_setup.ts': (await import('!!raw-loader!./scripts/run_setup.ts')).default,
'scripts/groth16/groth16_trusted_setup.ts': (await import('!!raw-loader!./scripts/groth16/groth16_trusted_setup.ts')).default,
// @ts-ignore
'scripts/run_verification.ts': (await import('!!raw-loader!./scripts/run_verification.ts')).default,
'scripts/groth16/groth16_zkproof.ts': (await import('!!raw-loader!./scripts/groth16/groth16_zkproof.ts')).default,
// @ts-ignore
'scripts/plonk/plonk_trusted_setup.ts': (await import('!!raw-loader!./scripts/plonk/plonk_trusted_setup.ts')).default,
// @ts-ignore
'scripts/plonk/plonk_zkproof.ts': (await import('!!raw-loader!./scripts/plonk/plonk_zkproof.ts')).default,
// @ts-ignore
'templates/groth16_verifier.sol.ejs': (await import('!!raw-loader!./templates/groth16_verifier.sol.ejs')).default,
// @ts-ignore
'templates/plonk_verifier.sol.ejs': (await import('!!raw-loader!./templates/plonk_verifier.sol.ejs')).default,
// @ts-ignore
'README.md': (await import('raw-loader!./README.md')).default
}
}

@ -13,7 +13,7 @@ const logger = {
const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmTiT4eiYz5KF7gQrDsgfCSTRv3wBPYJ4bRN1MmTRshpnW";
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.r1cs', true);
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.r1cs', { encoding: null });
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
const zkey_0 = { type: "mem" };
@ -39,17 +39,10 @@ const logger = {
console.log('exportVerificationKey')
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final)
await remix.call('fileManager', 'writeFile', './zk/build/verification_key.json', JSON.stringify(vKey))
await remix.call('fileManager', 'writeFile', './zk/keys/groth16/verification_key.json', JSON.stringify(vKey, null, 2))
const templates = {
groth16: await remix.call('fileManager', 'readFile', 'templates/groth16_verifier.sol.ejs')
}
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
await remix.call('fileManager', 'writeFile', './zk/build/zk_verifier.sol', solidityContract)
console.log('buffer', (zkey_final as any).data.length)
await remix.call('fileManager', 'writeFile', './zk/build/zk_setup.txt', JSON.stringify(Array.from(((zkey_final as any).data))))
console.log('save zkey_final')
await remix.call('fileManager', 'writeFile', './zk/keys/groth16/zkey_final.txt', JSON.stringify(Array.from(((zkey_final as any).data))))
console.log('setup done.')

@ -12,21 +12,23 @@ const logger = {
(async () => {
try {
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.r1cs', true);
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.r1cs', { encoding: null });
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.wasm', true);
await remix.call('circuit-compiler', 'compile', 'circuits/calculate_hash.circom');
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.wasm', { encoding: null });
// @ts-ignore
const wasm = new Uint8Array(wasmBuffer);
const zkey_final = {
type: "mem",
data: new Uint8Array(JSON.parse(await remix.call('fileManager', 'readFile', './zk/build/zk_setup.txt')))
data: new Uint8Array(JSON.parse(await remix.call('fileManager', 'readFile', './zk/keys/groth16/zkey_final.txt')))
}
const wtns = { type: "mem" };
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/build/verification_key.json'))
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/keys/groth16/verification_key.json'))
const value1 = '1234'
const value2 = '2'
@ -56,7 +58,18 @@ const logger = {
const verified = await snarkjs.groth16.verify(vKey, publicSignals, proof, logger);
console.log('zk proof validity', verified);
const templates = {
groth16: await remix.call('fileManager', 'readFile', 'templates/groth16_verifier.sol.ejs')
}
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
await remix.call('fileManager', 'writeFile', './zk/build/groth16/zk_verifier.sol', solidityContract)
await remix.call('fileManager', 'writeFile', 'zk/build/groth16/input.json', JSON.stringify({
_pA: [proof.pi_a[0], proof.pi_a[1]],
_pB: [[proof.pi_b[0][1], proof.pi_b[0][0]], [proof.pi_b[1][1], proof.pi_b[1][0]]],
_pC: [proof.pi_c[0], proof.pi_c[1]],
_pubSignals: publicSignals,
}, null, 2))
} catch (e) {
console.error(e.message)
}

@ -0,0 +1,32 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
(async () => {
try {
// @ts-ignore
await remix.call('circuit-compiler', 'generateR1cs', 'circuits/calculate_hash.circom');
const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmTiT4eiYz5KF7gQrDsgfCSTRv3wBPYJ4bRN1MmTRshpnW";
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.r1cs', { encoding: null });
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
const zkey_final = { type: "mem" };
console.log('plonk setup')
await snarkjs.plonk.setup(r1cs, ptau_final, zkey_final)
console.log('exportVerificationKey')
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final)
console.log('save zkey_final')
await remix.call('fileManager', 'writeFile', './zk/keys/plonk/zkey_final.txt', JSON.stringify(Array.from(((zkey_final as any).data))))
console.log('save verification key')
await remix.call('fileManager', 'writeFile', './zk/keys/plonk/verification_key.json', JSON.stringify(vKey, null, 2))
console.log('setup done')
} catch (e) {
console.error(e.message)
}
})()

@ -0,0 +1,93 @@
import { ethers, BigNumber } from 'ethers'
import { poseidon } from "circomlibjs" // v0.0.8
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
const logger = {
info: (...args) => console.log(...args),
debug: (...args) => console.log(...args),
error: (...args) => console.error(...args),
};
(async () => {
try {
// @ts-ignore
await remix.call('circuit-compiler', 'compile', 'circuits/calculate_hash.circom');
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.wasm', { encoding: null });
// @ts-ignore
const wasm = new Uint8Array(wasmBuffer);
const zkey_final = {
type: "mem",
data: new Uint8Array(JSON.parse(await remix.call('fileManager', 'readFile', './zk/keys/plonk/zkey_final.txt')))
}
const wtns = { type: "mem" };
const value1 = '1234'
const value2 = '2'
const value3 = '3'
const value4 = '4'
const wrongValue = '5' // put this in the poseidon hash calculation to simulate a non matching hash.
const signals = {
value1,
value2,
value3,
value4,
hash: poseidon([value1, value2, value3, value4])
}
console.log('calculate')
await snarkjs.wtns.calculate(signals, wasm, wtns, logger);
const { proof, publicSignals } = await snarkjs.plonk.prove(zkey_final, wtns);
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/keys/plonk/verification_key.json'))
const verified = await snarkjs.plonk.verify(vKey, publicSignals, proof);
console.log('zk proof validity', verified);
const templates = {
plonk: await remix.call('fileManager', 'readFile', 'templates/plonk_verifier.sol.ejs')
}
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
await remix.call('fileManager', 'writeFile', 'zk/build/plonk/zk_verifier.sol', solidityContract)
await remix.call('fileManager', 'writeFile', 'zk/build/plonk/input.json', JSON.stringify({
_proof: [
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.A[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.A[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.B[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.B[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.C[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.C[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Z[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Z[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T1[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T1[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T2[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T2[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T3[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T3[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxi[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxi[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxiw[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxiw[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_a).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_b).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_c).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_s1).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_s2).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_zw).toHexString(), 32),
],
_pubSignals: publicSignals
}, null, 2))
console.log('proof done.')
} catch (e) {
console.error(e.message)
}
})()

@ -0,0 +1,710 @@
// SPDX-License-Identifier: GPL-3.0
/*
Copyright 2021 0KIMS association.
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
pragma solidity >=0.7.0 <0.9.0;
import "hardhat/console.sol";
contract PlonkVerifier {
// Omega
uint256 constant w1 = <%=w%>;
// Scalar field size
uint256 constant q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
// Base field size
uint256 constant qf = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
// [1]_1
uint256 constant G1x = 1;
uint256 constant G1y = 2;
// [1]_2
uint256 constant G2x1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant G2x2 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant G2y1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant G2y2 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
// Verification Key data
uint32 constant n = <%=2**power%>;
uint16 constant nPublic = <%=nPublic%>;
uint16 constant nLagrange = <%=Math.max(nPublic, 1)%>;
uint256 constant Qmx = <%=Qm[0]%>;
uint256 constant Qmy = <%=Qm[0] == "0" ? "0" : Qm[1]%>;
uint256 constant Qlx = <%=Ql[0]%>;
uint256 constant Qly = <%=Ql[0] == "0" ? "0" : Ql[1]%>;
uint256 constant Qrx = <%=Qr[0]%>;
uint256 constant Qry = <%=Qr[0] == "0" ? "0" : Qr[1]%>;
uint256 constant Qox = <%=Qo[0]%>;
uint256 constant Qoy = <%=Qo[0] == "0" ? "0" : Qo[1]%>;
uint256 constant Qcx = <%=Qc[0]%>;
uint256 constant Qcy = <%=Qc[0] == "0" ? "0" : Qc[1]%>;
uint256 constant S1x = <%=S1[0]%>;
uint256 constant S1y = <%=S1[0] == "0" ? "0" : S1[1]%>;
uint256 constant S2x = <%=S2[0]%>;
uint256 constant S2y = <%=S2[0] == "0" ? "0" : S2[1]%>;
uint256 constant S3x = <%=S3[0]%>;
uint256 constant S3y = <%=S3[0] == "0" ? "0" : S3[1]%>;
uint256 constant k1 = <%=k1%>;
uint256 constant k2 = <%=k2%>;
uint256 constant X2x1 = <%=X_2[0][0]%>;
uint256 constant X2x2 = <%=X_2[0][1]%>;
uint256 constant X2y1 = <%=X_2[1][0]%>;
uint256 constant X2y2 = <%=X_2[1][1]%>;
// Proof calldata
// Byte offset of every parameter of the calldata
// Polynomial commitments
uint16 constant pA = 4 + 0;
uint16 constant pB = 4 + 64;
uint16 constant pC = 4 + 128;
uint16 constant pZ = 4 + 192;
uint16 constant pT1 = 4 + 256;
uint16 constant pT2 = 4 + 320;
uint16 constant pT3 = 4 + 384;
uint16 constant pWxi = 4 + 448;
uint16 constant pWxiw = 4 + 512;
// Opening evaluations
uint16 constant pEval_a = 4 + 576;
uint16 constant pEval_b = 4 + 608;
uint16 constant pEval_c = 4 + 640;
uint16 constant pEval_s1 = 4 + 672;
uint16 constant pEval_s2 = 4 + 704;
uint16 constant pEval_zw = 4 + 736;
// Memory data
// Challenges
uint16 constant pAlpha = 0;
uint16 constant pBeta = 32;
uint16 constant pGamma = 64;
uint16 constant pXi = 96;
uint16 constant pXin = 128;
uint16 constant pBetaXi = 160;
uint16 constant pV1 = 192;
uint16 constant pV2 = 224;
uint16 constant pV3 = 256;
uint16 constant pV4 = 288;
uint16 constant pV5 = 320;
uint16 constant pU = 352;
uint16 constant pPI = 384;
uint16 constant pEval_r0 = 416;
uint16 constant pD = 448;
uint16 constant pF = 512;
uint16 constant pE = 576;
uint16 constant pTmp = 640;
uint16 constant pAlpha2 = 704;
uint16 constant pZh = 736;
uint16 constant pZhInv = 768;
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
uint16 constant pEval_l<%=i%> = <%=768+i*32%>;
<% } %>
<% let pLastMem = 800+32*Math.max(nPublic,1) %>
uint16 constant lastMem = <%=pLastMem%>;
function verifyProof(uint256[24] calldata _proof, uint256[<%=nPublic%>] calldata _pubSignals) public view returns (bool) {
assembly {
/////////
// Computes the inverse using the extended euclidean algorithm
/////////
function inverse(a, q) -> inv {
let t := 0
let newt := 1
let r := q
let newr := a
let quotient
let aux
for { } newr { } {
quotient := sdiv(r, newr)
aux := sub(t, mul(quotient, newt))
t:= newt
newt:= aux
aux := sub(r,mul(quotient, newr))
r := newr
newr := aux
}
if gt(r, 1) { revert(0,0) }
if slt(t, 0) { t:= add(t, q) }
inv := t
}
///////
// Computes the inverse of an array of values
// See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations
//////
function inverseArray(pVals, n) {
let pAux := mload(0x40) // Point to the next free position
let pIn := pVals
let lastPIn := add(pVals, mul(n, 32)) // Read n elemnts
let acc := mload(pIn) // Read the first element
pIn := add(pIn, 32) // Point to the second element
let inv
for { } lt(pIn, lastPIn) {
pAux := add(pAux, 32)
pIn := add(pIn, 32)
}
{
mstore(pAux, acc)
acc := mulmod(acc, mload(pIn), q)
}
acc := inverse(acc, q)
// At this point pAux pint to the next free position we substract 1 to point to the last used
pAux := sub(pAux, 32)
// pIn points to the n+1 element, we substract to point to n
pIn := sub(pIn, 32)
lastPIn := pVals // We don't process the first element
for { } gt(pIn, lastPIn) {
pAux := sub(pAux, 32)
pIn := sub(pIn, 32)
}
{
inv := mulmod(acc, mload(pAux), q)
acc := mulmod(acc, mload(pIn), q)
mstore(pIn, inv)
}
// pIn points to first element, we just set it.
mstore(pIn, acc)
}
function checkField(v) {
if iszero(lt(v, q)) {
mstore(0, 0)
return(0,0x20)
}
}
function checkInput() {
checkField(calldataload(pEval_a))
checkField(calldataload(pEval_b))
checkField(calldataload(pEval_c))
checkField(calldataload(pEval_s1))
checkField(calldataload(pEval_s2))
checkField(calldataload(pEval_zw))
}
function calculateChallenges(pMem, pPublic) {
let beta
let aux
let mIn := mload(0x40) // Pointer to the next free memory position
// Compute challenge.beta & challenge.gamma
mstore(mIn, Qmx)
mstore(add(mIn, 32), Qmy)
mstore(add(mIn, 64), Qlx)
mstore(add(mIn, 96), Qly)
mstore(add(mIn, 128), Qrx)
mstore(add(mIn, 160), Qry)
mstore(add(mIn, 192), Qox)
mstore(add(mIn, 224), Qoy)
mstore(add(mIn, 256), Qcx)
mstore(add(mIn, 288), Qcy)
mstore(add(mIn, 320), S1x)
mstore(add(mIn, 352), S1y)
mstore(add(mIn, 384), S2x)
mstore(add(mIn, 416), S2y)
mstore(add(mIn, 448), S3x)
mstore(add(mIn, 480), S3y)
<%for (let i=0; i<nPublic;i++) {%>
mstore(add(mIn, <%= 512 + i*32 %>), calldataload(add(pPublic, <%=i*32%>)))
<%}%>
mstore(add(mIn, <%= 512 + nPublic*32 + 0 %> ), calldataload(pA))
mstore(add(mIn, <%= 512 + nPublic*32 + 32 %> ), calldataload(add(pA, 32)))
mstore(add(mIn, <%= 512 + nPublic*32 + 64 %> ), calldataload(pB))
mstore(add(mIn, <%= 512 + nPublic*32 + 96 %> ), calldataload(add(pB, 32)))
mstore(add(mIn, <%= 512 + nPublic*32 + 128 %> ), calldataload(pC))
mstore(add(mIn, <%= 512 + nPublic*32 + 160 %> ), calldataload(add(pC, 32)))
beta := mod(keccak256(mIn, <%= 704 + 32 * nPublic %>), q)
mstore(add(pMem, pBeta), beta)
// challenges.gamma
mstore(add(pMem, pGamma), mod(keccak256(add(pMem, pBeta), 32), q))
// challenges.alpha
mstore(mIn, mload(add(pMem, pBeta)))
mstore(add(mIn, 32), mload(add(pMem, pGamma)))
mstore(add(mIn, 64), calldataload(pZ))
mstore(add(mIn, 96), calldataload(add(pZ, 32)))
aux := mod(keccak256(mIn, 128), q)
mstore(add(pMem, pAlpha), aux)
mstore(add(pMem, pAlpha2), mulmod(aux, aux, q))
// challenges.xi
mstore(mIn, aux)
mstore(add(mIn, 32), calldataload(pT1))
mstore(add(mIn, 64), calldataload(add(pT1, 32)))
mstore(add(mIn, 96), calldataload(pT2))
mstore(add(mIn, 128), calldataload(add(pT2, 32)))
mstore(add(mIn, 160), calldataload(pT3))
mstore(add(mIn, 192), calldataload(add(pT3, 32)))
aux := mod(keccak256(mIn, 224), q)
mstore( add(pMem, pXi), aux)
// challenges.v
mstore(mIn, aux)
mstore(add(mIn, 32), calldataload(pEval_a))
mstore(add(mIn, 64), calldataload(pEval_b))
mstore(add(mIn, 96), calldataload(pEval_c))
mstore(add(mIn, 128), calldataload(pEval_s1))
mstore(add(mIn, 160), calldataload(pEval_s2))
mstore(add(mIn, 192), calldataload(pEval_zw))
let v1 := mod(keccak256(mIn, 224), q)
mstore(add(pMem, pV1), v1)
// challenges.beta * challenges.xi
mstore(add(pMem, pBetaXi), mulmod(beta, aux, q))
// challenges.xi^n
<%for (let i=0; i<power;i++) {%>
aux:= mulmod(aux, aux, q)
<%}%>
mstore(add(pMem, pXin), aux)
// Zh
aux:= mod(add(sub(aux, 1), q), q)
mstore(add(pMem, pZh), aux)
mstore(add(pMem, pZhInv), aux) // We will invert later together with lagrange pols
// challenges.v^2, challenges.v^3, challenges.v^4, challenges.v^5
aux := mulmod(v1, v1, q)
mstore(add(pMem, pV2), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV3), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV4), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV5), aux)
// challenges.u
mstore(mIn, calldataload(pWxi))
mstore(add(mIn, 32), calldataload(add(pWxi, 32)))
mstore(add(mIn, 64), calldataload(pWxiw))
mstore(add(mIn, 96), calldataload(add(pWxiw, 32)))
mstore(add(pMem, pU), mod(keccak256(mIn, 128), q))
}
function calculateLagrange(pMem) {
let w := 1
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
mstore(
add(pMem, pEval_l<%=i%>),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
<% if (i<Math.max(nPublic, 1)) { %>
w := mulmod(w, w1, q)
<% } %>
<% } %>
inverseArray(add(pMem, pZhInv), <%=Math.max(nPublic, 1)+1%> )
let zh := mload(add(pMem, pZh))
w := 1
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
<% if (i==1) { %>
mstore(
add(pMem, pEval_l1 ),
mulmod(
mload(add(pMem, pEval_l1 )),
zh,
q
)
)
<% } else { %>
mstore(
add(pMem, pEval_l<%=i%>),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l<%=i%>)),
zh,
q
),
q
)
)
<% } %>
<% if (i<Math.max(nPublic, 1)) { %>
w := mulmod(w, w1, q)
<% } %>
<% } %>
}
function calculatePI(pMem, pPub) {
let pl := 0
<% for (let i=0; i<nPublic; i++) { %>
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l<%=i+1%>)),
calldataload(add(pPub, <%=i*32%>)),
q
)
),
q
),
q
)
<% } %>
mstore(add(pMem, pPI), pl)
}
function calculateR0(pMem) {
let e1 := mload(add(pMem, pPI))
let e2 := mulmod(mload(add(pMem, pEval_l1)), mload(add(pMem, pAlpha2)), q)
let e3a := addmod(
calldataload(pEval_a),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s1), q),
q)
e3a := addmod(e3a, mload(add(pMem, pGamma)), q)
let e3b := addmod(
calldataload(pEval_b),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s2), q),
q)
e3b := addmod(e3b, mload(add(pMem, pGamma)), q)
let e3c := addmod(
calldataload(pEval_c),
mload(add(pMem, pGamma)),
q)
let e3 := mulmod(mulmod(e3a, e3b, q), e3c, q)
e3 := mulmod(e3, calldataload(pEval_zw), q)
e3 := mulmod(e3, mload(add(pMem, pAlpha)), q)
let r0 := addmod(e1, mod(sub(q, e2), q), q)
r0 := addmod(r0, mod(sub(q, e3), q), q)
mstore(add(pMem, pEval_r0) , r0)
}
function g1_set(pR, pP) {
mstore(pR, mload(pP))
mstore(add(pR, 32), mload(add(pP,32)))
}
function g1_setC(pR, x, y) {
mstore(pR, x)
mstore(add(pR, 32), y)
}
function g1_calldataSet(pR, pP) {
mstore(pR, calldataload(pP))
mstore(add(pR, 32), calldataload(add(pP, 32)))
}
function g1_acc(pR, pP) {
let mIn := mload(0x40)
mstore(mIn, mload(pR))
mstore(add(mIn,32), mload(add(pR, 32)))
mstore(add(mIn,64), mload(pP))
mstore(add(mIn,96), mload(add(pP, 32)))
let success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAcc(pR, pP, s) {
let success
let mIn := mload(0x40)
mstore(mIn, mload(pP))
mstore(add(mIn,32), mload(add(pP, 32)))
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSetC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSet(pR, pP, s) {
g1_mulSetC(pR, mload(pP), mload(add(pP, 32)), s)
}
function calculateD(pMem) {
let _pD:= add(pMem, pD)
let gamma := mload(add(pMem, pGamma))
let mIn := mload(0x40)
mstore(0x40, add(mIn, 256)) // d1, d2, d3 & d4 (4*64 bytes)
g1_setC(_pD, Qcx, Qcy)
g1_mulAccC(_pD, Qmx, Qmy, mulmod(calldataload(pEval_a), calldataload(pEval_b), q))
g1_mulAccC(_pD, Qlx, Qly, calldataload(pEval_a))
g1_mulAccC(_pD, Qrx, Qry, calldataload(pEval_b))
g1_mulAccC(_pD, Qox, Qoy, calldataload(pEval_c))
let betaxi := mload(add(pMem, pBetaXi))
let val1 := addmod(
addmod(calldataload(pEval_a), betaxi, q),
gamma, q)
let val2 := addmod(
addmod(
calldataload(pEval_b),
mulmod(betaxi, k1, q),
q), gamma, q)
let val3 := addmod(
addmod(
calldataload(pEval_c),
mulmod(betaxi, k2, q),
q), gamma, q)
let d2a := mulmod(
mulmod(mulmod(val1, val2, q), val3, q),
mload(add(pMem, pAlpha)),
q
)
let d2b := mulmod(
mload(add(pMem, pEval_l1)),
mload(add(pMem, pAlpha2)),
q
)
// We'll use mIn to save d2
g1_calldataSet(add(mIn, 192), pZ)
g1_mulSet(
mIn,
add(mIn, 192),
addmod(addmod(d2a, d2b, q), mload(add(pMem, pU)), q))
val1 := addmod(
addmod(
calldataload(pEval_a),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s1), q),
q), gamma, q)
val2 := addmod(
addmod(
calldataload(pEval_b),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s2), q),
q), gamma, q)
val3 := mulmod(
mulmod(mload(add(pMem, pAlpha)), mload(add(pMem, pBeta)), q),
calldataload(pEval_zw), q)
// We'll use mIn + 64 to save d3
g1_mulSetC(
add(mIn, 64),
S3x,
S3y,
mulmod(mulmod(val1, val2, q), val3, q))
// We'll use mIn + 128 to save d4
g1_calldataSet(add(mIn, 128), pT1)
g1_mulAccC(add(mIn, 128), calldataload(pT2), calldataload(add(pT2, 32)), mload(add(pMem, pXin)))
let xin2 := mulmod(mload(add(pMem, pXin)), mload(add(pMem, pXin)), q)
g1_mulAccC(add(mIn, 128), calldataload(pT3), calldataload(add(pT3, 32)) , xin2)
g1_mulSetC(add(mIn, 128), mload(add(mIn, 128)), mload(add(mIn, 160)), mload(add(pMem, pZh)))
mstore(add(add(mIn, 64), 32), mod(sub(qf, mload(add(add(mIn, 64), 32))), qf))
mstore(add(mIn, 160), mod(sub(qf, mload(add(mIn, 160))), qf))
g1_acc(_pD, mIn)
g1_acc(_pD, add(mIn, 64))
g1_acc(_pD, add(mIn, 128))
}
function calculateF(pMem) {
let p := add(pMem, pF)
g1_set(p, add(pMem, pD))
g1_mulAccC(p, calldataload(pA), calldataload(add(pA, 32)), mload(add(pMem, pV1)))
g1_mulAccC(p, calldataload(pB), calldataload(add(pB, 32)), mload(add(pMem, pV2)))
g1_mulAccC(p, calldataload(pC), calldataload(add(pC, 32)), mload(add(pMem, pV3)))
g1_mulAccC(p, S1x, S1y, mload(add(pMem, pV4)))
g1_mulAccC(p, S2x, S2y, mload(add(pMem, pV5)))
}
function calculateE(pMem) {
let s := mod(sub(q, mload(add(pMem, pEval_r0))), q)
s := addmod(s, mulmod(calldataload(pEval_a), mload(add(pMem, pV1)), q), q)
s := addmod(s, mulmod(calldataload(pEval_b), mload(add(pMem, pV2)), q), q)
s := addmod(s, mulmod(calldataload(pEval_c), mload(add(pMem, pV3)), q), q)
s := addmod(s, mulmod(calldataload(pEval_s1), mload(add(pMem, pV4)), q), q)
s := addmod(s, mulmod(calldataload(pEval_s2), mload(add(pMem, pV5)), q), q)
s := addmod(s, mulmod(calldataload(pEval_zw), mload(add(pMem, pU)), q), q)
g1_mulSetC(add(pMem, pE), G1x, G1y, s)
}
function checkPairing(pMem) -> isOk {
let mIn := mload(0x40)
mstore(0x40, add(mIn, 576)) // [0..383] = pairing data, [384..447] = pWxi, [448..512] = pWxiw
let _pWxi := add(mIn, 384)
let _pWxiw := add(mIn, 448)
let _aux := add(mIn, 512)
g1_calldataSet(_pWxi, pWxi)
g1_calldataSet(_pWxiw, pWxiw)
// A1
g1_mulSet(mIn, _pWxiw, mload(add(pMem, pU)))
g1_acc(mIn, _pWxi)
mstore(add(mIn, 32), mod(sub(qf, mload(add(mIn, 32))), qf))
// [X]_2
mstore(add(mIn,64), X2x2)
mstore(add(mIn,96), X2x1)
mstore(add(mIn,128), X2y2)
mstore(add(mIn,160), X2y1)
// B1
g1_mulSet(add(mIn, 192), _pWxi, mload(add(pMem, pXi)))
let s := mulmod(mload(add(pMem, pU)), mload(add(pMem, pXi)), q)
s := mulmod(s, w1, q)
g1_mulSet(_aux, _pWxiw, s)
g1_acc(add(mIn, 192), _aux)
g1_acc(add(mIn, 192), add(pMem, pF))
mstore(add(pMem, add(pE, 32)), mod(sub(qf, mload(add(pMem, add(pE, 32)))), qf))
g1_acc(add(mIn, 192), add(pMem, pE))
// [1]_2
mstore(add(mIn,256), G2x2)
mstore(add(mIn,288), G2x1)
mstore(add(mIn,320), G2y2)
mstore(add(mIn,352), G2y1)
let success := staticcall(sub(gas(), 2000), 8, mIn, 384, mIn, 0x20)
isOk := and(success, mload(mIn))
}
let pMem := mload(0x40)
mstore(0x40, add(pMem, lastMem))
checkInput()
calculateChallenges(pMem, _pubSignals)
calculateLagrange(pMem)
calculatePI(pMem, _pubSignals)
calculateR0(pMem)
calculateD(pMem)
calculateF(pMem)
calculateE(pMem)
let isValid := checkPairing(pMem)
mstore(0x40, sub(pMem, lastMem))
mstore(0, isValid)
return(0,0x20)
}
}
}

@ -7,12 +7,18 @@ export default async () => {
// @ts-ignore
'circuits/withdraw.circom': (await import('!!raw-loader!./circuits/withdraw.circom')).default,
// @ts-ignore
'scripts/run_setup.ts': (await import('!!raw-loader!./scripts/run_setup.ts')).default,
'scripts/groth16/groth16_trusted_setup.ts': (await import('!!raw-loader!./scripts/groth16/groth16_trusted_setup.ts')).default,
// @ts-ignore
'scripts/run_verification.ts': (await import('!!raw-loader!./scripts/run_verification.ts')).default,
'scripts/groth16/groth16_zkproof.ts': (await import('!!raw-loader!./scripts/groth16/groth16_zkproof.ts')).default,
// @ts-ignore
'scripts/plonk/plonk_trusted_setup.ts': (await import('!!raw-loader!./scripts/plonk/plonk_trusted_setup.ts')).default,
// @ts-ignore
'scripts/plonk/plonk_zkproof.ts': (await import('!!raw-loader!./scripts/plonk/plonk_zkproof.ts')).default,
// @ts-ignore
'templates/groth16_verifier.sol.ejs': (await import('!!raw-loader!./templates/groth16_verifier.sol.ejs')).default,
// @ts-ignore
'templates/plonk_verifier.sol.ejs': (await import('!!raw-loader!./templates/plonk_verifier.sol.ejs')).default,
// @ts-ignore
'LICENSE-APACHE': (await import('!!raw-loader!./LICENSE-APACHE')).default,
// @ts-ignore
'LICENSE-MIT': (await import('!!raw-loader!./LICENSE-MIT')).default,

@ -13,7 +13,7 @@ const logger = {
const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmTiT4eiYz5KF7gQrDsgfCSTRv3wBPYJ4bRN1MmTRshpnW";
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.r1cs', true);
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.r1cs', { encoding: null });
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
const zkey_0 = { type: "mem" };
@ -39,17 +39,10 @@ const logger = {
console.log('exportVerificationKey')
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final)
await remix.call('fileManager', 'writeFile', './zk/build/verification_key.json', JSON.stringify(vKey))
await remix.call('fileManager', 'writeFile', './zk/keys/groth16/verification_key.json', JSON.stringify(vKey, null, 2))
const templates = {
groth16: await remix.call('fileManager', 'readFile', 'templates/groth16_verifier.sol.ejs')
}
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
await remix.call('fileManager', 'writeFile', './zk/build/zk_verifier.sol', solidityContract)
console.log('buffer', (zkey_final as any).data.length)
await remix.call('fileManager', 'writeFile', './zk/build/zk_setup.txt', JSON.stringify(Array.from(((zkey_final as any).data))))
console.log('save zkey_final')
await remix.call('fileManager', 'writeFile', './zk/keys/groth16/zkey_final.txt', (zkey_final as any).data, { encoding: null })
console.log('setup done.')

@ -54,6 +54,15 @@ async function prove (signals, wasm, wtns, r1cs, zkey_final, vKey) {
const verified = await snarkjs.groth16.verify(vKey, publicSignals, proof, logger);
console.log('zk proof validity', verified);
await remix.call('fileManager', 'writeFile', `zk/build/groth16/input-${Date.now()}.json`, JSON.stringify({
_pA: [proof.pi_a[0], proof.pi_a[1]],
_pB: [[proof.pi_b[0][1], proof.pi_b[0][0]], [proof.pi_b[1][1], proof.pi_b[1][0]]],
_pC: [proof.pi_c[0], proof.pi_c[1]],
_pubSignals: publicSignals,
}, null, 2))
console.log('proof done.')
return {
proof,
x: publicSignals[3],
@ -64,21 +73,23 @@ async function prove (signals, wasm, wtns, r1cs, zkey_final, vKey) {
(async () => {
try {
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.r1cs', true);
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.r1cs', { encoding: null });
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.wasm', true);
await remix.call('circuit-compiler', 'compile', 'circuits/rln.circom');
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.wasm', { encoding: null });
// @ts-ignore
const wasm = new Uint8Array(wasmBuffer);
const zkey_final = {
type: "mem",
data: new Uint8Array(JSON.parse(await remix.call('fileManager', 'readFile', './zk/build/zk_setup.txt')))
data: new Uint8Array(await remix.call('fileManager', 'readFile', './zk/keys/groth16/zkey_final.txt', { encoding: null }))
}
const wtns = { type: "mem" };
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/build/verification_key.json'))
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/keys/groth16/verification_key.json'))
// build list of identity commitments
const secrets = []
@ -135,6 +146,13 @@ async function prove (signals, wasm, wtns, r1cs, zkey_final, vKey) {
console.log(secret.toString(10))
console.log(Fq.normalize(secrets[0]))
const templates = {
groth16: await remix.call('fileManager', 'readFile', 'templates/groth16_verifier.sol.ejs')
}
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
await remix.call('fileManager', 'writeFile', './zk/build/groth16/zk_verifier.sol', solidityContract)
} catch (e) {
console.error(e.message)
}

@ -0,0 +1,33 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
(async () => {
try {
// @ts-ignore
await remix.call('circuit-compiler', 'generateR1cs', 'circuits/rln.circom');
const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmciCq5JcZQyTLvC9GRanrLBi82ZmSriq1Fr5zANkGHebf";
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.r1cs', { encoding: null });
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
const zkey_final = { type: "mem" };
console.log('plonk setup')
await snarkjs.plonk.setup(r1cs, ptau_final, zkey_final)
console.log('exportVerificationKey')
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final)
console.log('save zkey_final')
// @ts-ignore
await remix.call('fileManager', 'writeFile', './zk/keys/plonk/zkey_final.txt', (zkey_final as any).data, { encoding: null })
console.log('save verification key')
await remix.call('fileManager', 'writeFile', './zk/keys/plonk/verification_key.json', JSON.stringify(vKey, null, 2))
console.log('setup done')
} catch (e) {
console.error(e.message)
}
})()

@ -0,0 +1,183 @@
import { ethers, BigNumber } from 'ethers'
import { IncrementalMerkleTree } from "@zk-kit/incremental-merkle-tree"
import { poseidon } from "circomlibjs" // v0.0.8
import { ZqField } from 'ffjavascript'
const SNARK_FIELD_SIZE = BigInt('21888242871839275222246405745257275088548364400416034343698204186575808495617')
// Creates the finite field
const Fq = new ZqField(SNARK_FIELD_SIZE)
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
const logger = {
info: (...args) => console.log(...args),
debug: (...args) => console.log(...args),
error: (...args) => console.error(...args),
}
/**
* Recovers secret from two shares
* @param x1 signal hash of first message
* @param x2 signal hash of second message
* @param y1 yshare of first message
* @param y2 yshare of second message
* @returns identity secret
*/
function shamirRecovery(x1: bigint, x2: bigint, y1: bigint, y2: bigint): bigint {
const slope = Fq.div(Fq.sub(y2, y1), Fq.sub(x2, x1))
const privateKey = Fq.sub(y1, Fq.mul(slope, x1))
return Fq.normalize(privateKey)
}
function hash(message: any): bigint {
message = BigNumber.from(message).toTwos(256).toHexString()
message = ethers.utils.zeroPad(message, 32)
return BigInt(ethers.utils.keccak256(message)) >> BigInt(8)
}
function hashNullifier(message: any): bigint {
return BigInt(ethers.utils.keccak256(message)) >> BigInt(8)
}
async function prove (signals, wasm, wtns, r1cs, zkey_final, vKey) {
console.log('calculate')
await snarkjs.wtns.calculate(signals, wasm, wtns);
console.log('check')
await snarkjs.wtns.check(r1cs, wtns, logger);
console.log('prove')
const { proof, publicSignals } = await snarkjs.plonk.prove(zkey_final, wtns);
const verified = await snarkjs.plonk.verify(vKey, publicSignals, proof, logger);
console.log('zk proof validity', verified);
await remix.call('fileManager', 'writeFile', `zk/build/plonk/input-${Date.now()}.json`, JSON.stringify({
_pubSignals: publicSignals,
_proof: [
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.A[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.A[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.B[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.B[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.C[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.C[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Z[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Z[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T1[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T1[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T2[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T2[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T3[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T3[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxi[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxi[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxiw[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxiw[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_a).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_b).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_c).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_s1).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_s2).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_zw).toHexString(), 32),
]
}, null, 2))
console.log('proof done.')
return {
proof,
x: publicSignals[3],
y: publicSignals[0]
}
}
(async () => {
try {
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.r1cs', { encoding: null });
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
// @ts-ignore
await remix.call('circuit-compiler', 'compile', 'circuits/rln.circom');
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.wasm', { encoding: null });
// @ts-ignore
const wasm = new Uint8Array(wasmBuffer);
const zkey_final = {
type: "mem",
// @ts-ignore
data: new Uint8Array(await remix.call('fileManager', 'readFile', './zk/keys/plonk/zkey_final.txt', { encoding: null }))
}
const wtns = { type: "mem" };
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/keys/plonk/verification_key.json'))
// build list of identity commitments
const secrets = []
const identityCommitments = []
const rateCommitments = []
const userMessageLimit = 0x2
for (let k = 0; k < 2; k++) {
const identitySecret = BigInt(ethers.utils.hexlify(ethers.utils.randomBytes(32)))
secrets.push(identitySecret)
const identityCommitment = poseidon([identitySecret])
const rateCommitment = poseidon([identityCommitment, userMessageLimit])
identityCommitments.push(identityCommitment)
rateCommitments.push(rateCommitment)
}
let tree
try {
tree = new IncrementalMerkleTree(poseidon, 20, BigInt(0), 2, rateCommitments) // Binary tree.
} catch (e) {
console.error(e.message)
return
}
const merkleproof1 = tree.createProof(0)
const appId = 0xa
const epoch = 0x1
const signals1 = {
identitySecret: secrets[0],
userMessageLimit,
messageId: 0x0,
pathElements: merkleproof1.siblings,
identityPathIndex: merkleproof1.pathIndices,
x: 0xabcd, // hash(message)
externalNullifier: 0xa // hash(epoch, appId)
}
const proof1 = await prove(signals1, wasm, wtns, r1cs, zkey_final, vKey)
const signals2 = {
identitySecret: secrets[0],
userMessageLimit,
messageId: 0x0,
pathElements: merkleproof1.siblings,
identityPathIndex: merkleproof1.pathIndices,
x: 0xabce, // hash(message)
externalNullifier: 0xa // hash(epoch, appId)
}
const proof2 = await prove(signals2, wasm, wtns, r1cs, zkey_final, vKey)
const secret = shamirRecovery(BigInt(proof1.x), BigInt(proof2.x), BigInt(proof1.y), BigInt(proof2.y))
console.log(secret.toString(10))
console.log(Fq.normalize(secrets[0]))
const templates = {
plonk: await remix.call('fileManager', 'readFile', 'templates/plonk_verifier.sol.ejs')
}
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
await remix.call('fileManager', 'writeFile', './zk/build/plonk/zk_verifier.sol', solidityContract)
} catch (e) {
console.error(e.message)
}
})()

@ -0,0 +1,710 @@
// SPDX-License-Identifier: GPL-3.0
/*
Copyright 2021 0KIMS association.
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
pragma solidity >=0.7.0 <0.9.0;
import "hardhat/console.sol";
contract PlonkVerifier {
// Omega
uint256 constant w1 = <%=w%>;
// Scalar field size
uint256 constant q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
// Base field size
uint256 constant qf = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
// [1]_1
uint256 constant G1x = 1;
uint256 constant G1y = 2;
// [1]_2
uint256 constant G2x1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant G2x2 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant G2y1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant G2y2 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
// Verification Key data
uint32 constant n = <%=2**power%>;
uint16 constant nPublic = <%=nPublic%>;
uint16 constant nLagrange = <%=Math.max(nPublic, 1)%>;
uint256 constant Qmx = <%=Qm[0]%>;
uint256 constant Qmy = <%=Qm[0] == "0" ? "0" : Qm[1]%>;
uint256 constant Qlx = <%=Ql[0]%>;
uint256 constant Qly = <%=Ql[0] == "0" ? "0" : Ql[1]%>;
uint256 constant Qrx = <%=Qr[0]%>;
uint256 constant Qry = <%=Qr[0] == "0" ? "0" : Qr[1]%>;
uint256 constant Qox = <%=Qo[0]%>;
uint256 constant Qoy = <%=Qo[0] == "0" ? "0" : Qo[1]%>;
uint256 constant Qcx = <%=Qc[0]%>;
uint256 constant Qcy = <%=Qc[0] == "0" ? "0" : Qc[1]%>;
uint256 constant S1x = <%=S1[0]%>;
uint256 constant S1y = <%=S1[0] == "0" ? "0" : S1[1]%>;
uint256 constant S2x = <%=S2[0]%>;
uint256 constant S2y = <%=S2[0] == "0" ? "0" : S2[1]%>;
uint256 constant S3x = <%=S3[0]%>;
uint256 constant S3y = <%=S3[0] == "0" ? "0" : S3[1]%>;
uint256 constant k1 = <%=k1%>;
uint256 constant k2 = <%=k2%>;
uint256 constant X2x1 = <%=X_2[0][0]%>;
uint256 constant X2x2 = <%=X_2[0][1]%>;
uint256 constant X2y1 = <%=X_2[1][0]%>;
uint256 constant X2y2 = <%=X_2[1][1]%>;
// Proof calldata
// Byte offset of every parameter of the calldata
// Polynomial commitments
uint16 constant pA = 4 + 0;
uint16 constant pB = 4 + 64;
uint16 constant pC = 4 + 128;
uint16 constant pZ = 4 + 192;
uint16 constant pT1 = 4 + 256;
uint16 constant pT2 = 4 + 320;
uint16 constant pT3 = 4 + 384;
uint16 constant pWxi = 4 + 448;
uint16 constant pWxiw = 4 + 512;
// Opening evaluations
uint16 constant pEval_a = 4 + 576;
uint16 constant pEval_b = 4 + 608;
uint16 constant pEval_c = 4 + 640;
uint16 constant pEval_s1 = 4 + 672;
uint16 constant pEval_s2 = 4 + 704;
uint16 constant pEval_zw = 4 + 736;
// Memory data
// Challenges
uint16 constant pAlpha = 0;
uint16 constant pBeta = 32;
uint16 constant pGamma = 64;
uint16 constant pXi = 96;
uint16 constant pXin = 128;
uint16 constant pBetaXi = 160;
uint16 constant pV1 = 192;
uint16 constant pV2 = 224;
uint16 constant pV3 = 256;
uint16 constant pV4 = 288;
uint16 constant pV5 = 320;
uint16 constant pU = 352;
uint16 constant pPI = 384;
uint16 constant pEval_r0 = 416;
uint16 constant pD = 448;
uint16 constant pF = 512;
uint16 constant pE = 576;
uint16 constant pTmp = 640;
uint16 constant pAlpha2 = 704;
uint16 constant pZh = 736;
uint16 constant pZhInv = 768;
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
uint16 constant pEval_l<%=i%> = <%=768+i*32%>;
<% } %>
<% let pLastMem = 800+32*Math.max(nPublic,1) %>
uint16 constant lastMem = <%=pLastMem%>;
function verifyProof(uint256[24] calldata _proof, uint256[<%=nPublic%>] calldata _pubSignals) public view returns (bool) {
assembly {
/////////
// Computes the inverse using the extended euclidean algorithm
/////////
function inverse(a, q) -> inv {
let t := 0
let newt := 1
let r := q
let newr := a
let quotient
let aux
for { } newr { } {
quotient := sdiv(r, newr)
aux := sub(t, mul(quotient, newt))
t:= newt
newt:= aux
aux := sub(r,mul(quotient, newr))
r := newr
newr := aux
}
if gt(r, 1) { revert(0,0) }
if slt(t, 0) { t:= add(t, q) }
inv := t
}
///////
// Computes the inverse of an array of values
// See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations
//////
function inverseArray(pVals, n) {
let pAux := mload(0x40) // Point to the next free position
let pIn := pVals
let lastPIn := add(pVals, mul(n, 32)) // Read n elemnts
let acc := mload(pIn) // Read the first element
pIn := add(pIn, 32) // Point to the second element
let inv
for { } lt(pIn, lastPIn) {
pAux := add(pAux, 32)
pIn := add(pIn, 32)
}
{
mstore(pAux, acc)
acc := mulmod(acc, mload(pIn), q)
}
acc := inverse(acc, q)
// At this point pAux pint to the next free position we substract 1 to point to the last used
pAux := sub(pAux, 32)
// pIn points to the n+1 element, we substract to point to n
pIn := sub(pIn, 32)
lastPIn := pVals // We don't process the first element
for { } gt(pIn, lastPIn) {
pAux := sub(pAux, 32)
pIn := sub(pIn, 32)
}
{
inv := mulmod(acc, mload(pAux), q)
acc := mulmod(acc, mload(pIn), q)
mstore(pIn, inv)
}
// pIn points to first element, we just set it.
mstore(pIn, acc)
}
function checkField(v) {
if iszero(lt(v, q)) {
mstore(0, 0)
return(0,0x20)
}
}
function checkInput() {
checkField(calldataload(pEval_a))
checkField(calldataload(pEval_b))
checkField(calldataload(pEval_c))
checkField(calldataload(pEval_s1))
checkField(calldataload(pEval_s2))
checkField(calldataload(pEval_zw))
}
function calculateChallenges(pMem, pPublic) {
let beta
let aux
let mIn := mload(0x40) // Pointer to the next free memory position
// Compute challenge.beta & challenge.gamma
mstore(mIn, Qmx)
mstore(add(mIn, 32), Qmy)
mstore(add(mIn, 64), Qlx)
mstore(add(mIn, 96), Qly)
mstore(add(mIn, 128), Qrx)
mstore(add(mIn, 160), Qry)
mstore(add(mIn, 192), Qox)
mstore(add(mIn, 224), Qoy)
mstore(add(mIn, 256), Qcx)
mstore(add(mIn, 288), Qcy)
mstore(add(mIn, 320), S1x)
mstore(add(mIn, 352), S1y)
mstore(add(mIn, 384), S2x)
mstore(add(mIn, 416), S2y)
mstore(add(mIn, 448), S3x)
mstore(add(mIn, 480), S3y)
<%for (let i=0; i<nPublic;i++) {%>
mstore(add(mIn, <%= 512 + i*32 %>), calldataload(add(pPublic, <%=i*32%>)))
<%}%>
mstore(add(mIn, <%= 512 + nPublic*32 + 0 %> ), calldataload(pA))
mstore(add(mIn, <%= 512 + nPublic*32 + 32 %> ), calldataload(add(pA, 32)))
mstore(add(mIn, <%= 512 + nPublic*32 + 64 %> ), calldataload(pB))
mstore(add(mIn, <%= 512 + nPublic*32 + 96 %> ), calldataload(add(pB, 32)))
mstore(add(mIn, <%= 512 + nPublic*32 + 128 %> ), calldataload(pC))
mstore(add(mIn, <%= 512 + nPublic*32 + 160 %> ), calldataload(add(pC, 32)))
beta := mod(keccak256(mIn, <%= 704 + 32 * nPublic %>), q)
mstore(add(pMem, pBeta), beta)
// challenges.gamma
mstore(add(pMem, pGamma), mod(keccak256(add(pMem, pBeta), 32), q))
// challenges.alpha
mstore(mIn, mload(add(pMem, pBeta)))
mstore(add(mIn, 32), mload(add(pMem, pGamma)))
mstore(add(mIn, 64), calldataload(pZ))
mstore(add(mIn, 96), calldataload(add(pZ, 32)))
aux := mod(keccak256(mIn, 128), q)
mstore(add(pMem, pAlpha), aux)
mstore(add(pMem, pAlpha2), mulmod(aux, aux, q))
// challenges.xi
mstore(mIn, aux)
mstore(add(mIn, 32), calldataload(pT1))
mstore(add(mIn, 64), calldataload(add(pT1, 32)))
mstore(add(mIn, 96), calldataload(pT2))
mstore(add(mIn, 128), calldataload(add(pT2, 32)))
mstore(add(mIn, 160), calldataload(pT3))
mstore(add(mIn, 192), calldataload(add(pT3, 32)))
aux := mod(keccak256(mIn, 224), q)
mstore( add(pMem, pXi), aux)
// challenges.v
mstore(mIn, aux)
mstore(add(mIn, 32), calldataload(pEval_a))
mstore(add(mIn, 64), calldataload(pEval_b))
mstore(add(mIn, 96), calldataload(pEval_c))
mstore(add(mIn, 128), calldataload(pEval_s1))
mstore(add(mIn, 160), calldataload(pEval_s2))
mstore(add(mIn, 192), calldataload(pEval_zw))
let v1 := mod(keccak256(mIn, 224), q)
mstore(add(pMem, pV1), v1)
// challenges.beta * challenges.xi
mstore(add(pMem, pBetaXi), mulmod(beta, aux, q))
// challenges.xi^n
<%for (let i=0; i<power;i++) {%>
aux:= mulmod(aux, aux, q)
<%}%>
mstore(add(pMem, pXin), aux)
// Zh
aux:= mod(add(sub(aux, 1), q), q)
mstore(add(pMem, pZh), aux)
mstore(add(pMem, pZhInv), aux) // We will invert later together with lagrange pols
// challenges.v^2, challenges.v^3, challenges.v^4, challenges.v^5
aux := mulmod(v1, v1, q)
mstore(add(pMem, pV2), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV3), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV4), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV5), aux)
// challenges.u
mstore(mIn, calldataload(pWxi))
mstore(add(mIn, 32), calldataload(add(pWxi, 32)))
mstore(add(mIn, 64), calldataload(pWxiw))
mstore(add(mIn, 96), calldataload(add(pWxiw, 32)))
mstore(add(pMem, pU), mod(keccak256(mIn, 128), q))
}
function calculateLagrange(pMem) {
let w := 1
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
mstore(
add(pMem, pEval_l<%=i%>),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
<% if (i<Math.max(nPublic, 1)) { %>
w := mulmod(w, w1, q)
<% } %>
<% } %>
inverseArray(add(pMem, pZhInv), <%=Math.max(nPublic, 1)+1%> )
let zh := mload(add(pMem, pZh))
w := 1
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
<% if (i==1) { %>
mstore(
add(pMem, pEval_l1 ),
mulmod(
mload(add(pMem, pEval_l1 )),
zh,
q
)
)
<% } else { %>
mstore(
add(pMem, pEval_l<%=i%>),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l<%=i%>)),
zh,
q
),
q
)
)
<% } %>
<% if (i<Math.max(nPublic, 1)) { %>
w := mulmod(w, w1, q)
<% } %>
<% } %>
}
function calculatePI(pMem, pPub) {
let pl := 0
<% for (let i=0; i<nPublic; i++) { %>
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l<%=i+1%>)),
calldataload(add(pPub, <%=i*32%>)),
q
)
),
q
),
q
)
<% } %>
mstore(add(pMem, pPI), pl)
}
function calculateR0(pMem) {
let e1 := mload(add(pMem, pPI))
let e2 := mulmod(mload(add(pMem, pEval_l1)), mload(add(pMem, pAlpha2)), q)
let e3a := addmod(
calldataload(pEval_a),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s1), q),
q)
e3a := addmod(e3a, mload(add(pMem, pGamma)), q)
let e3b := addmod(
calldataload(pEval_b),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s2), q),
q)
e3b := addmod(e3b, mload(add(pMem, pGamma)), q)
let e3c := addmod(
calldataload(pEval_c),
mload(add(pMem, pGamma)),
q)
let e3 := mulmod(mulmod(e3a, e3b, q), e3c, q)
e3 := mulmod(e3, calldataload(pEval_zw), q)
e3 := mulmod(e3, mload(add(pMem, pAlpha)), q)
let r0 := addmod(e1, mod(sub(q, e2), q), q)
r0 := addmod(r0, mod(sub(q, e3), q), q)
mstore(add(pMem, pEval_r0) , r0)
}
function g1_set(pR, pP) {
mstore(pR, mload(pP))
mstore(add(pR, 32), mload(add(pP,32)))
}
function g1_setC(pR, x, y) {
mstore(pR, x)
mstore(add(pR, 32), y)
}
function g1_calldataSet(pR, pP) {
mstore(pR, calldataload(pP))
mstore(add(pR, 32), calldataload(add(pP, 32)))
}
function g1_acc(pR, pP) {
let mIn := mload(0x40)
mstore(mIn, mload(pR))
mstore(add(mIn,32), mload(add(pR, 32)))
mstore(add(mIn,64), mload(pP))
mstore(add(mIn,96), mload(add(pP, 32)))
let success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAcc(pR, pP, s) {
let success
let mIn := mload(0x40)
mstore(mIn, mload(pP))
mstore(add(mIn,32), mload(add(pP, 32)))
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSetC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSet(pR, pP, s) {
g1_mulSetC(pR, mload(pP), mload(add(pP, 32)), s)
}
function calculateD(pMem) {
let _pD:= add(pMem, pD)
let gamma := mload(add(pMem, pGamma))
let mIn := mload(0x40)
mstore(0x40, add(mIn, 256)) // d1, d2, d3 & d4 (4*64 bytes)
g1_setC(_pD, Qcx, Qcy)
g1_mulAccC(_pD, Qmx, Qmy, mulmod(calldataload(pEval_a), calldataload(pEval_b), q))
g1_mulAccC(_pD, Qlx, Qly, calldataload(pEval_a))
g1_mulAccC(_pD, Qrx, Qry, calldataload(pEval_b))
g1_mulAccC(_pD, Qox, Qoy, calldataload(pEval_c))
let betaxi := mload(add(pMem, pBetaXi))
let val1 := addmod(
addmod(calldataload(pEval_a), betaxi, q),
gamma, q)
let val2 := addmod(
addmod(
calldataload(pEval_b),
mulmod(betaxi, k1, q),
q), gamma, q)
let val3 := addmod(
addmod(
calldataload(pEval_c),
mulmod(betaxi, k2, q),
q), gamma, q)
let d2a := mulmod(
mulmod(mulmod(val1, val2, q), val3, q),
mload(add(pMem, pAlpha)),
q
)
let d2b := mulmod(
mload(add(pMem, pEval_l1)),
mload(add(pMem, pAlpha2)),
q
)
// We'll use mIn to save d2
g1_calldataSet(add(mIn, 192), pZ)
g1_mulSet(
mIn,
add(mIn, 192),
addmod(addmod(d2a, d2b, q), mload(add(pMem, pU)), q))
val1 := addmod(
addmod(
calldataload(pEval_a),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s1), q),
q), gamma, q)
val2 := addmod(
addmod(
calldataload(pEval_b),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s2), q),
q), gamma, q)
val3 := mulmod(
mulmod(mload(add(pMem, pAlpha)), mload(add(pMem, pBeta)), q),
calldataload(pEval_zw), q)
// We'll use mIn + 64 to save d3
g1_mulSetC(
add(mIn, 64),
S3x,
S3y,
mulmod(mulmod(val1, val2, q), val3, q))
// We'll use mIn + 128 to save d4
g1_calldataSet(add(mIn, 128), pT1)
g1_mulAccC(add(mIn, 128), calldataload(pT2), calldataload(add(pT2, 32)), mload(add(pMem, pXin)))
let xin2 := mulmod(mload(add(pMem, pXin)), mload(add(pMem, pXin)), q)
g1_mulAccC(add(mIn, 128), calldataload(pT3), calldataload(add(pT3, 32)) , xin2)
g1_mulSetC(add(mIn, 128), mload(add(mIn, 128)), mload(add(mIn, 160)), mload(add(pMem, pZh)))
mstore(add(add(mIn, 64), 32), mod(sub(qf, mload(add(add(mIn, 64), 32))), qf))
mstore(add(mIn, 160), mod(sub(qf, mload(add(mIn, 160))), qf))
g1_acc(_pD, mIn)
g1_acc(_pD, add(mIn, 64))
g1_acc(_pD, add(mIn, 128))
}
function calculateF(pMem) {
let p := add(pMem, pF)
g1_set(p, add(pMem, pD))
g1_mulAccC(p, calldataload(pA), calldataload(add(pA, 32)), mload(add(pMem, pV1)))
g1_mulAccC(p, calldataload(pB), calldataload(add(pB, 32)), mload(add(pMem, pV2)))
g1_mulAccC(p, calldataload(pC), calldataload(add(pC, 32)), mload(add(pMem, pV3)))
g1_mulAccC(p, S1x, S1y, mload(add(pMem, pV4)))
g1_mulAccC(p, S2x, S2y, mload(add(pMem, pV5)))
}
function calculateE(pMem) {
let s := mod(sub(q, mload(add(pMem, pEval_r0))), q)
s := addmod(s, mulmod(calldataload(pEval_a), mload(add(pMem, pV1)), q), q)
s := addmod(s, mulmod(calldataload(pEval_b), mload(add(pMem, pV2)), q), q)
s := addmod(s, mulmod(calldataload(pEval_c), mload(add(pMem, pV3)), q), q)
s := addmod(s, mulmod(calldataload(pEval_s1), mload(add(pMem, pV4)), q), q)
s := addmod(s, mulmod(calldataload(pEval_s2), mload(add(pMem, pV5)), q), q)
s := addmod(s, mulmod(calldataload(pEval_zw), mload(add(pMem, pU)), q), q)
g1_mulSetC(add(pMem, pE), G1x, G1y, s)
}
function checkPairing(pMem) -> isOk {
let mIn := mload(0x40)
mstore(0x40, add(mIn, 576)) // [0..383] = pairing data, [384..447] = pWxi, [448..512] = pWxiw
let _pWxi := add(mIn, 384)
let _pWxiw := add(mIn, 448)
let _aux := add(mIn, 512)
g1_calldataSet(_pWxi, pWxi)
g1_calldataSet(_pWxiw, pWxiw)
// A1
g1_mulSet(mIn, _pWxiw, mload(add(pMem, pU)))
g1_acc(mIn, _pWxi)
mstore(add(mIn, 32), mod(sub(qf, mload(add(mIn, 32))), qf))
// [X]_2
mstore(add(mIn,64), X2x2)
mstore(add(mIn,96), X2x1)
mstore(add(mIn,128), X2y2)
mstore(add(mIn,160), X2y1)
// B1
g1_mulSet(add(mIn, 192), _pWxi, mload(add(pMem, pXi)))
let s := mulmod(mload(add(pMem, pU)), mload(add(pMem, pXi)), q)
s := mulmod(s, w1, q)
g1_mulSet(_aux, _pWxiw, s)
g1_acc(add(mIn, 192), _aux)
g1_acc(add(mIn, 192), add(pMem, pF))
mstore(add(pMem, add(pE, 32)), mod(sub(qf, mload(add(pMem, add(pE, 32)))), qf))
g1_acc(add(mIn, 192), add(pMem, pE))
// [1]_2
mstore(add(mIn,256), G2x2)
mstore(add(mIn,288), G2x1)
mstore(add(mIn,320), G2y2)
mstore(add(mIn,352), G2y1)
let success := staticcall(sub(gas(), 2000), 8, mIn, 384, mIn, 0x20)
isOk := and(success, mload(mIn))
}
let pMem := mload(0x40)
mstore(0x40, add(pMem, lastMem))
checkInput()
calculateChallenges(pMem, _pubSignals)
calculateLagrange(pMem)
calculatePI(pMem, _pubSignals)
calculateR0(pMem)
calculateD(pMem)
calculateF(pMem)
calculateE(pMem)
let isValid := checkPairing(pMem)
mstore(0x40, sub(pMem, lastMem))
mstore(0, isValid)
return(0,0x20)
}
}
}

@ -3,16 +3,22 @@ export default async () => {
// @ts-ignore
'circuits/semaphore.circom': (await import('raw-loader!./circuits/semaphore.circom')).default,
// @ts-ignore
'circuits/tree.circom': (await import('!!raw-loader!./circuits/tree.circom')).default,
// @ts-ignore
'circuits/simple.circom': (await import('!!raw-loader!./circuits/simple.circom')).default,
// @ts-ignore
'circuits/tree.circom': (await import('!!raw-loader!./circuits/tree.circom')).default,
'scripts/groth16/groth16_trusted_setup.ts': (await import('!!raw-loader!./scripts/groth16/groth16_trusted_setup.ts')).default,
// @ts-ignore
'scripts/run_setup.ts': (await import('!!raw-loader!./scripts/run_setup.ts')).default,
'scripts/groth16/groth16_zkproof.ts': (await import('!!raw-loader!./scripts/groth16/groth16_zkproof.ts')).default,
// @ts-ignore
'scripts/run_verification.ts': (await import('!!raw-loader!./scripts/run_verification.ts')).default,
'scripts/plonk/plonk_trusted_setup.ts': (await import('!!raw-loader!./scripts/plonk/plonk_trusted_setup.ts')).default,
// @ts-ignore
'scripts/plonk/plonk_zkproof.ts': (await import('!!raw-loader!./scripts/plonk/plonk_zkproof.ts')).default,
// @ts-ignore
'templates/groth16_verifier.sol.ejs': (await import('!!raw-loader!./templates/groth16_verifier.sol.ejs')).default,
// @ts-ignore
'templates/plonk_verifier.sol.ejs': (await import('!!raw-loader!./templates/plonk_verifier.sol.ejs')).default,
// @ts-ignore
'README.md': (await import('raw-loader!./README.md')).default
}
}

@ -0,0 +1,53 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
const logger = {
info: (...args) => console.log(...args),
debug: (...args) => console.log(...args)
};
(async () => {
try {
// @ts-ignore
await remix.call('circuit-compiler', 'generateR1cs', 'circuits/semaphore.circom');
const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmTiT4eiYz5KF7gQrDsgfCSTRv3wBPYJ4bRN1MmTRshpnW";
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/semaphore.r1cs', { encoding: null });
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
const zkey_0 = { type: "mem" };
const zkey_1 = { type: "mem" };
const zkey_final = { type: "mem" };
console.log('newZkey')
await snarkjs.zKey.newZKey(r1cs, ptau_final, zkey_0);
console.log('contribute')
await snarkjs.zKey.contribute(zkey_0, zkey_1, "p2_C1", "pa_Entropy1");
console.log('beacon')
await snarkjs.zKey.beacon(zkey_1, zkey_final, "B3", "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", 10);
console.log('verifyFromR1cs')
const verifyFromR1csResult = await snarkjs.zKey.verifyFromR1cs(r1cs, ptau_final, zkey_final);
console.assert(verifyFromR1csResult);
console.log('verifyFromInit')
const verifyFromInit = await snarkjs.zKey.verifyFromInit(zkey_0, ptau_final, zkey_final);
console.assert(verifyFromInit);
console.log('exportVerificationKey')
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final)
await remix.call('fileManager', 'writeFile', './zk/keys/groth16/verification_key.json', JSON.stringify(vKey, null, 2))
console.log('save zkey_final')
// @ts-ignore
await remix.call('fileManager', 'writeFile', './zk/keys/groth16/zkey_final.txt', (zkey_final as any).data, { encoding: null })
console.log('setup done.')
} catch (e) {
console.error(e.message)
}
})()

@ -0,0 +1,114 @@
import { ethers, BigNumber } from 'ethers'
import { IncrementalMerkleTree } from "@zk-kit/incremental-merkle-tree"
import { poseidon } from "circomlibjs" // v0.0.8
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
const logger = {
info: (...args) => console.log(...args),
debug: (...args) => console.log(...args),
error: (...args) => console.error(...args),
}
/**
* Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
* @param message The message to be hashed.
* @returns The message digest.
*/
function hash(message: any): bigint {
message = BigNumber.from(message).toTwos(256).toHexString()
message = ethers.utils.zeroPad(message, 32)
return BigInt(ethers.utils.keccak256(message)) >> BigInt(8)
}
(async () => {
try {
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/semaphore.r1cs', true);
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
// @ts-ignore
await remix.call('circuit-compiler', 'compile', 'circuits/semaphore.circom');
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/semaphore.wasm', true);
// @ts-ignore
const wasm = new Uint8Array(wasmBuffer);
const zkey_final = {
type: "mem",
// @ts-ignore
data: new Uint8Array(await remix.call('fileManager', 'readFile', './zk/keys/groth16/zkey_final.txt', { encoding: null }))
}
const wtns = { type: "mem" };
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/keys/groth16/verification_key.json'))
// build list of identity commitments
const secrets = []
const identityCommitments = []
for (let k = 0; k < 2; k++) {
const identityTrapdoor = BigInt(ethers.utils.hexlify(ethers.utils.randomBytes(32)))
const identityNullifier = BigInt(ethers.utils.hexlify(ethers.utils.randomBytes(32)))
secrets.push({identityTrapdoor, identityNullifier})
const secret = poseidon([identityNullifier, identityTrapdoor])
const identityCommitment = poseidon([secret])
identityCommitments.push(identityCommitment)
}
//console.log('incremental tree', identityCommitments.map((x) => x.toString()))
let tree
try {
tree = new IncrementalMerkleTree(poseidon, 20, BigInt(0), 2, identityCommitments) // Binary tree.
} catch (e) {
console.error(e.message)
return
}
const index = tree.indexOf(identityCommitments[0])
console.log(index.toString())
const proof1 = tree.createProof(0)
console.log('prepare signals for id ', identityCommitments[0].toString(), tree.indexOf(identityCommitments[0]), proof1.siblings.map((x)=> x.toString()))
const signals = {
identityTrapdoor: secrets[0].identityTrapdoor,
identityNullifier: secrets[0].identityNullifier,
treePathIndices: proof1.pathIndices,
treeSiblings: proof1.siblings,
externalNullifier: hash(42),
signalHash: hash(ethers.utils.formatBytes32String("Hello World"))
}
console.log('calculate')
await snarkjs.wtns.calculate(signals, wasm, wtns);
console.log('check')
await snarkjs.wtns.check(r1cs, wtns, logger);
console.log('prove')
const { proof, publicSignals } = await snarkjs.groth16.prove(zkey_final, wtns);
const verified = await snarkjs.groth16.verify(vKey, publicSignals, proof, logger);
console.log('zk proof validity', verified);
proof1.root.toString() === publicSignals[0] ? console.log('merkle proof valid') : console.log('merkle proof invalid')
const templates = {
groth16: await remix.call('fileManager', 'readFile', 'templates/groth16_verifier.sol.ejs')
}
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
await remix.call('fileManager', 'writeFile', './zk/build/groth16/zk_verifier.sol', solidityContract)
await remix.call('fileManager', 'writeFile', 'zk/build/groth16/input.json', JSON.stringify({
_pA: [proof.pi_a[0], proof.pi_a[1]],
_pB: [[proof.pi_b[0][1], proof.pi_b[0][0]], [proof.pi_b[1][1], proof.pi_b[1][0]]],
_pC: [proof.pi_c[0], proof.pi_c[1]],
_pubSignals: publicSignals
}, null, 2))
} catch (e) {
console.error(e.message)
}
})()

@ -0,0 +1,37 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
const logger = {
info: (...args) => console.log(...args),
debug: (...args) => console.log(...args)
};
(async () => {
try {
// @ts-ignore
await remix.call('circuit-compiler', 'generateR1cs', 'circuits/semaphore.circom');
const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmciCq5JcZQyTLvC9GRanrLBi82ZmSriq1Fr5zANkGHebf";
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/semaphore.r1cs', { encoding: null });
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
const zkey_final = { type: "mem" };
console.log('plonk setup')
await snarkjs.plonk.setup(r1cs, ptau_final, zkey_final)
console.log('exportVerificationKey')
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final)
await remix.call('fileManager', 'writeFile', './zk/keys/plonk/verification_key.json', JSON.stringify(vKey, null, 2))
console.log('save zkey_final')
// @ts-ignore
await remix.call('fileManager', 'writeFile', './zk/keys/plonk/zkey_final.txt', (zkey_final as any).data, { encoding: null })
console.log('setup done.')
} catch (e) {
console.error(e.message)
}
})()

@ -0,0 +1,139 @@
import { ethers, BigNumber } from 'ethers'
import { IncrementalMerkleTree } from "@zk-kit/incremental-merkle-tree"
import { poseidon } from "circomlibjs" // v0.0.8
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
const logger = {
info: (...args) => console.log(...args),
debug: (...args) => console.log(...args),
error: (...args) => console.error(...args),
}
/**
* Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
* @param message The message to be hashed.
* @returns The message digest.
*/
function hash(message: any): bigint {
message = BigNumber.from(message).toTwos(256).toHexString()
message = ethers.utils.zeroPad(message, 32)
return BigInt(ethers.utils.keccak256(message)) >> BigInt(8)
}
(async () => {
try {
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/semaphore.r1cs', true);
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
// @ts-ignore
await remix.call('circuit-compiler', 'compile', 'circuits/semaphore.circom');
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/semaphore.wasm', true);
// @ts-ignore
const wasm = new Uint8Array(wasmBuffer);
const zkey_final = {
type: "mem",
// @ts-ignore
data: new Uint8Array(await remix.call('fileManager', 'readFile', './zk/keys/plonk/zkey_final.txt', { encoding: null }))
}
const wtns = { type: "mem" };
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/keys/plonk/verification_key.json'))
// build list of identity commitments
const secrets = []
const identityCommitments = []
for (let k = 0; k < 2; k++) {
const identityTrapdoor = BigInt(ethers.utils.hexlify(ethers.utils.randomBytes(32)))
const identityNullifier = BigInt(ethers.utils.hexlify(ethers.utils.randomBytes(32)))
secrets.push({identityTrapdoor, identityNullifier})
const secret = poseidon([identityNullifier, identityTrapdoor])
const identityCommitment = poseidon([secret])
identityCommitments.push(identityCommitment)
}
//console.log('incremental tree', identityCommitments.map((x) => x.toString()))
let tree
try {
tree = new IncrementalMerkleTree(poseidon, 20, BigInt(0), 2, identityCommitments) // Binary tree.
} catch (e) {
console.error(e.message)
return
}
const index = tree.indexOf(identityCommitments[0])
console.log(index.toString())
const proof1 = tree.createProof(0)
console.log('prepare signals for id ', identityCommitments[0].toString(), tree.indexOf(identityCommitments[0]), proof1.siblings.map((x)=> x.toString()))
const signals = {
identityTrapdoor: secrets[0].identityTrapdoor,
identityNullifier: secrets[0].identityNullifier,
treePathIndices: proof1.pathIndices,
treeSiblings: proof1.siblings,
externalNullifier: hash(42),
signalHash: hash(ethers.utils.formatBytes32String("Hello World"))
}
console.log('calculate')
await snarkjs.wtns.calculate(signals, wasm, wtns);
console.log('check')
await snarkjs.wtns.check(r1cs, wtns, logger);
console.log('prove')
const { proof, publicSignals } = await snarkjs.plonk.prove(zkey_final, wtns);
const verified = await snarkjs.plonk.verify(vKey, publicSignals, proof, logger);
console.log('zk proof validity', verified);
proof1.root.toString() === publicSignals[0] ? console.log('merkle proof valid') : console.log('merkle proof invalid')
const templates = {
plonk: await remix.call('fileManager', 'readFile', 'templates/plonk_verifier.sol.ejs')
}
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
await remix.call('fileManager', 'writeFile', './zk/build/plonk/zk_verifier.sol', solidityContract)
await remix.call('fileManager', 'writeFile', 'zk/build/plonk/input.json', JSON.stringify({
_proof: [
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.A[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.A[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.B[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.B[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.C[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.C[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Z[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Z[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T1[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T1[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T2[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T2[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T3[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.T3[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxi[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxi[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxiw[0]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.Wxiw[1]).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_a).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_b).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_c).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_s1).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_s2).toHexString(), 32),
ethers.utils.hexZeroPad(ethers.BigNumber.from(proof.eval_zw).toHexString(), 32),
],
_pubSignals: publicSignals
}, null, 2))
console.log('proof done.')
} catch (e) {
console.error(e.message)
}
})()

@ -0,0 +1,710 @@
// SPDX-License-Identifier: GPL-3.0
/*
Copyright 2021 0KIMS association.
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
pragma solidity >=0.7.0 <0.9.0;
import "hardhat/console.sol";
contract PlonkVerifier {
// Omega
uint256 constant w1 = <%=w%>;
// Scalar field size
uint256 constant q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
// Base field size
uint256 constant qf = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
// [1]_1
uint256 constant G1x = 1;
uint256 constant G1y = 2;
// [1]_2
uint256 constant G2x1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant G2x2 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant G2y1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant G2y2 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
// Verification Key data
uint32 constant n = <%=2**power%>;
uint16 constant nPublic = <%=nPublic%>;
uint16 constant nLagrange = <%=Math.max(nPublic, 1)%>;
uint256 constant Qmx = <%=Qm[0]%>;
uint256 constant Qmy = <%=Qm[0] == "0" ? "0" : Qm[1]%>;
uint256 constant Qlx = <%=Ql[0]%>;
uint256 constant Qly = <%=Ql[0] == "0" ? "0" : Ql[1]%>;
uint256 constant Qrx = <%=Qr[0]%>;
uint256 constant Qry = <%=Qr[0] == "0" ? "0" : Qr[1]%>;
uint256 constant Qox = <%=Qo[0]%>;
uint256 constant Qoy = <%=Qo[0] == "0" ? "0" : Qo[1]%>;
uint256 constant Qcx = <%=Qc[0]%>;
uint256 constant Qcy = <%=Qc[0] == "0" ? "0" : Qc[1]%>;
uint256 constant S1x = <%=S1[0]%>;
uint256 constant S1y = <%=S1[0] == "0" ? "0" : S1[1]%>;
uint256 constant S2x = <%=S2[0]%>;
uint256 constant S2y = <%=S2[0] == "0" ? "0" : S2[1]%>;
uint256 constant S3x = <%=S3[0]%>;
uint256 constant S3y = <%=S3[0] == "0" ? "0" : S3[1]%>;
uint256 constant k1 = <%=k1%>;
uint256 constant k2 = <%=k2%>;
uint256 constant X2x1 = <%=X_2[0][0]%>;
uint256 constant X2x2 = <%=X_2[0][1]%>;
uint256 constant X2y1 = <%=X_2[1][0]%>;
uint256 constant X2y2 = <%=X_2[1][1]%>;
// Proof calldata
// Byte offset of every parameter of the calldata
// Polynomial commitments
uint16 constant pA = 4 + 0;
uint16 constant pB = 4 + 64;
uint16 constant pC = 4 + 128;
uint16 constant pZ = 4 + 192;
uint16 constant pT1 = 4 + 256;
uint16 constant pT2 = 4 + 320;
uint16 constant pT3 = 4 + 384;
uint16 constant pWxi = 4 + 448;
uint16 constant pWxiw = 4 + 512;
// Opening evaluations
uint16 constant pEval_a = 4 + 576;
uint16 constant pEval_b = 4 + 608;
uint16 constant pEval_c = 4 + 640;
uint16 constant pEval_s1 = 4 + 672;
uint16 constant pEval_s2 = 4 + 704;
uint16 constant pEval_zw = 4 + 736;
// Memory data
// Challenges
uint16 constant pAlpha = 0;
uint16 constant pBeta = 32;
uint16 constant pGamma = 64;
uint16 constant pXi = 96;
uint16 constant pXin = 128;
uint16 constant pBetaXi = 160;
uint16 constant pV1 = 192;
uint16 constant pV2 = 224;
uint16 constant pV3 = 256;
uint16 constant pV4 = 288;
uint16 constant pV5 = 320;
uint16 constant pU = 352;
uint16 constant pPI = 384;
uint16 constant pEval_r0 = 416;
uint16 constant pD = 448;
uint16 constant pF = 512;
uint16 constant pE = 576;
uint16 constant pTmp = 640;
uint16 constant pAlpha2 = 704;
uint16 constant pZh = 736;
uint16 constant pZhInv = 768;
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
uint16 constant pEval_l<%=i%> = <%=768+i*32%>;
<% } %>
<% let pLastMem = 800+32*Math.max(nPublic,1) %>
uint16 constant lastMem = <%=pLastMem%>;
function verifyProof(uint256[24] calldata _proof, uint256[<%=nPublic%>] calldata _pubSignals) public view returns (bool) {
assembly {
/////////
// Computes the inverse using the extended euclidean algorithm
/////////
function inverse(a, q) -> inv {
let t := 0
let newt := 1
let r := q
let newr := a
let quotient
let aux
for { } newr { } {
quotient := sdiv(r, newr)
aux := sub(t, mul(quotient, newt))
t:= newt
newt:= aux
aux := sub(r,mul(quotient, newr))
r := newr
newr := aux
}
if gt(r, 1) { revert(0,0) }
if slt(t, 0) { t:= add(t, q) }
inv := t
}
///////
// Computes the inverse of an array of values
// See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations
//////
function inverseArray(pVals, n) {
let pAux := mload(0x40) // Point to the next free position
let pIn := pVals
let lastPIn := add(pVals, mul(n, 32)) // Read n elemnts
let acc := mload(pIn) // Read the first element
pIn := add(pIn, 32) // Point to the second element
let inv
for { } lt(pIn, lastPIn) {
pAux := add(pAux, 32)
pIn := add(pIn, 32)
}
{
mstore(pAux, acc)
acc := mulmod(acc, mload(pIn), q)
}
acc := inverse(acc, q)
// At this point pAux pint to the next free position we substract 1 to point to the last used
pAux := sub(pAux, 32)
// pIn points to the n+1 element, we substract to point to n
pIn := sub(pIn, 32)
lastPIn := pVals // We don't process the first element
for { } gt(pIn, lastPIn) {
pAux := sub(pAux, 32)
pIn := sub(pIn, 32)
}
{
inv := mulmod(acc, mload(pAux), q)
acc := mulmod(acc, mload(pIn), q)
mstore(pIn, inv)
}
// pIn points to first element, we just set it.
mstore(pIn, acc)
}
function checkField(v) {
if iszero(lt(v, q)) {
mstore(0, 0)
return(0,0x20)
}
}
function checkInput() {
checkField(calldataload(pEval_a))
checkField(calldataload(pEval_b))
checkField(calldataload(pEval_c))
checkField(calldataload(pEval_s1))
checkField(calldataload(pEval_s2))
checkField(calldataload(pEval_zw))
}
function calculateChallenges(pMem, pPublic) {
let beta
let aux
let mIn := mload(0x40) // Pointer to the next free memory position
// Compute challenge.beta & challenge.gamma
mstore(mIn, Qmx)
mstore(add(mIn, 32), Qmy)
mstore(add(mIn, 64), Qlx)
mstore(add(mIn, 96), Qly)
mstore(add(mIn, 128), Qrx)
mstore(add(mIn, 160), Qry)
mstore(add(mIn, 192), Qox)
mstore(add(mIn, 224), Qoy)
mstore(add(mIn, 256), Qcx)
mstore(add(mIn, 288), Qcy)
mstore(add(mIn, 320), S1x)
mstore(add(mIn, 352), S1y)
mstore(add(mIn, 384), S2x)
mstore(add(mIn, 416), S2y)
mstore(add(mIn, 448), S3x)
mstore(add(mIn, 480), S3y)
<%for (let i=0; i<nPublic;i++) {%>
mstore(add(mIn, <%= 512 + i*32 %>), calldataload(add(pPublic, <%=i*32%>)))
<%}%>
mstore(add(mIn, <%= 512 + nPublic*32 + 0 %> ), calldataload(pA))
mstore(add(mIn, <%= 512 + nPublic*32 + 32 %> ), calldataload(add(pA, 32)))
mstore(add(mIn, <%= 512 + nPublic*32 + 64 %> ), calldataload(pB))
mstore(add(mIn, <%= 512 + nPublic*32 + 96 %> ), calldataload(add(pB, 32)))
mstore(add(mIn, <%= 512 + nPublic*32 + 128 %> ), calldataload(pC))
mstore(add(mIn, <%= 512 + nPublic*32 + 160 %> ), calldataload(add(pC, 32)))
beta := mod(keccak256(mIn, <%= 704 + 32 * nPublic %>), q)
mstore(add(pMem, pBeta), beta)
// challenges.gamma
mstore(add(pMem, pGamma), mod(keccak256(add(pMem, pBeta), 32), q))
// challenges.alpha
mstore(mIn, mload(add(pMem, pBeta)))
mstore(add(mIn, 32), mload(add(pMem, pGamma)))
mstore(add(mIn, 64), calldataload(pZ))
mstore(add(mIn, 96), calldataload(add(pZ, 32)))
aux := mod(keccak256(mIn, 128), q)
mstore(add(pMem, pAlpha), aux)
mstore(add(pMem, pAlpha2), mulmod(aux, aux, q))
// challenges.xi
mstore(mIn, aux)
mstore(add(mIn, 32), calldataload(pT1))
mstore(add(mIn, 64), calldataload(add(pT1, 32)))
mstore(add(mIn, 96), calldataload(pT2))
mstore(add(mIn, 128), calldataload(add(pT2, 32)))
mstore(add(mIn, 160), calldataload(pT3))
mstore(add(mIn, 192), calldataload(add(pT3, 32)))
aux := mod(keccak256(mIn, 224), q)
mstore( add(pMem, pXi), aux)
// challenges.v
mstore(mIn, aux)
mstore(add(mIn, 32), calldataload(pEval_a))
mstore(add(mIn, 64), calldataload(pEval_b))
mstore(add(mIn, 96), calldataload(pEval_c))
mstore(add(mIn, 128), calldataload(pEval_s1))
mstore(add(mIn, 160), calldataload(pEval_s2))
mstore(add(mIn, 192), calldataload(pEval_zw))
let v1 := mod(keccak256(mIn, 224), q)
mstore(add(pMem, pV1), v1)
// challenges.beta * challenges.xi
mstore(add(pMem, pBetaXi), mulmod(beta, aux, q))
// challenges.xi^n
<%for (let i=0; i<power;i++) {%>
aux:= mulmod(aux, aux, q)
<%}%>
mstore(add(pMem, pXin), aux)
// Zh
aux:= mod(add(sub(aux, 1), q), q)
mstore(add(pMem, pZh), aux)
mstore(add(pMem, pZhInv), aux) // We will invert later together with lagrange pols
// challenges.v^2, challenges.v^3, challenges.v^4, challenges.v^5
aux := mulmod(v1, v1, q)
mstore(add(pMem, pV2), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV3), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV4), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV5), aux)
// challenges.u
mstore(mIn, calldataload(pWxi))
mstore(add(mIn, 32), calldataload(add(pWxi, 32)))
mstore(add(mIn, 64), calldataload(pWxiw))
mstore(add(mIn, 96), calldataload(add(pWxiw, 32)))
mstore(add(pMem, pU), mod(keccak256(mIn, 128), q))
}
function calculateLagrange(pMem) {
let w := 1
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
mstore(
add(pMem, pEval_l<%=i%>),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
<% if (i<Math.max(nPublic, 1)) { %>
w := mulmod(w, w1, q)
<% } %>
<% } %>
inverseArray(add(pMem, pZhInv), <%=Math.max(nPublic, 1)+1%> )
let zh := mload(add(pMem, pZh))
w := 1
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
<% if (i==1) { %>
mstore(
add(pMem, pEval_l1 ),
mulmod(
mload(add(pMem, pEval_l1 )),
zh,
q
)
)
<% } else { %>
mstore(
add(pMem, pEval_l<%=i%>),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l<%=i%>)),
zh,
q
),
q
)
)
<% } %>
<% if (i<Math.max(nPublic, 1)) { %>
w := mulmod(w, w1, q)
<% } %>
<% } %>
}
function calculatePI(pMem, pPub) {
let pl := 0
<% for (let i=0; i<nPublic; i++) { %>
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l<%=i+1%>)),
calldataload(add(pPub, <%=i*32%>)),
q
)
),
q
),
q
)
<% } %>
mstore(add(pMem, pPI), pl)
}
function calculateR0(pMem) {
let e1 := mload(add(pMem, pPI))
let e2 := mulmod(mload(add(pMem, pEval_l1)), mload(add(pMem, pAlpha2)), q)
let e3a := addmod(
calldataload(pEval_a),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s1), q),
q)
e3a := addmod(e3a, mload(add(pMem, pGamma)), q)
let e3b := addmod(
calldataload(pEval_b),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s2), q),
q)
e3b := addmod(e3b, mload(add(pMem, pGamma)), q)
let e3c := addmod(
calldataload(pEval_c),
mload(add(pMem, pGamma)),
q)
let e3 := mulmod(mulmod(e3a, e3b, q), e3c, q)
e3 := mulmod(e3, calldataload(pEval_zw), q)
e3 := mulmod(e3, mload(add(pMem, pAlpha)), q)
let r0 := addmod(e1, mod(sub(q, e2), q), q)
r0 := addmod(r0, mod(sub(q, e3), q), q)
mstore(add(pMem, pEval_r0) , r0)
}
function g1_set(pR, pP) {
mstore(pR, mload(pP))
mstore(add(pR, 32), mload(add(pP,32)))
}
function g1_setC(pR, x, y) {
mstore(pR, x)
mstore(add(pR, 32), y)
}
function g1_calldataSet(pR, pP) {
mstore(pR, calldataload(pP))
mstore(add(pR, 32), calldataload(add(pP, 32)))
}
function g1_acc(pR, pP) {
let mIn := mload(0x40)
mstore(mIn, mload(pR))
mstore(add(mIn,32), mload(add(pR, 32)))
mstore(add(mIn,64), mload(pP))
mstore(add(mIn,96), mload(add(pP, 32)))
let success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAcc(pR, pP, s) {
let success
let mIn := mload(0x40)
mstore(mIn, mload(pP))
mstore(add(mIn,32), mload(add(pP, 32)))
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSetC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSet(pR, pP, s) {
g1_mulSetC(pR, mload(pP), mload(add(pP, 32)), s)
}
function calculateD(pMem) {
let _pD:= add(pMem, pD)
let gamma := mload(add(pMem, pGamma))
let mIn := mload(0x40)
mstore(0x40, add(mIn, 256)) // d1, d2, d3 & d4 (4*64 bytes)
g1_setC(_pD, Qcx, Qcy)
g1_mulAccC(_pD, Qmx, Qmy, mulmod(calldataload(pEval_a), calldataload(pEval_b), q))
g1_mulAccC(_pD, Qlx, Qly, calldataload(pEval_a))
g1_mulAccC(_pD, Qrx, Qry, calldataload(pEval_b))
g1_mulAccC(_pD, Qox, Qoy, calldataload(pEval_c))
let betaxi := mload(add(pMem, pBetaXi))
let val1 := addmod(
addmod(calldataload(pEval_a), betaxi, q),
gamma, q)
let val2 := addmod(
addmod(
calldataload(pEval_b),
mulmod(betaxi, k1, q),
q), gamma, q)
let val3 := addmod(
addmod(
calldataload(pEval_c),
mulmod(betaxi, k2, q),
q), gamma, q)
let d2a := mulmod(
mulmod(mulmod(val1, val2, q), val3, q),
mload(add(pMem, pAlpha)),
q
)
let d2b := mulmod(
mload(add(pMem, pEval_l1)),
mload(add(pMem, pAlpha2)),
q
)
// We'll use mIn to save d2
g1_calldataSet(add(mIn, 192), pZ)
g1_mulSet(
mIn,
add(mIn, 192),
addmod(addmod(d2a, d2b, q), mload(add(pMem, pU)), q))
val1 := addmod(
addmod(
calldataload(pEval_a),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s1), q),
q), gamma, q)
val2 := addmod(
addmod(
calldataload(pEval_b),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s2), q),
q), gamma, q)
val3 := mulmod(
mulmod(mload(add(pMem, pAlpha)), mload(add(pMem, pBeta)), q),
calldataload(pEval_zw), q)
// We'll use mIn + 64 to save d3
g1_mulSetC(
add(mIn, 64),
S3x,
S3y,
mulmod(mulmod(val1, val2, q), val3, q))
// We'll use mIn + 128 to save d4
g1_calldataSet(add(mIn, 128), pT1)
g1_mulAccC(add(mIn, 128), calldataload(pT2), calldataload(add(pT2, 32)), mload(add(pMem, pXin)))
let xin2 := mulmod(mload(add(pMem, pXin)), mload(add(pMem, pXin)), q)
g1_mulAccC(add(mIn, 128), calldataload(pT3), calldataload(add(pT3, 32)) , xin2)
g1_mulSetC(add(mIn, 128), mload(add(mIn, 128)), mload(add(mIn, 160)), mload(add(pMem, pZh)))
mstore(add(add(mIn, 64), 32), mod(sub(qf, mload(add(add(mIn, 64), 32))), qf))
mstore(add(mIn, 160), mod(sub(qf, mload(add(mIn, 160))), qf))
g1_acc(_pD, mIn)
g1_acc(_pD, add(mIn, 64))
g1_acc(_pD, add(mIn, 128))
}
function calculateF(pMem) {
let p := add(pMem, pF)
g1_set(p, add(pMem, pD))
g1_mulAccC(p, calldataload(pA), calldataload(add(pA, 32)), mload(add(pMem, pV1)))
g1_mulAccC(p, calldataload(pB), calldataload(add(pB, 32)), mload(add(pMem, pV2)))
g1_mulAccC(p, calldataload(pC), calldataload(add(pC, 32)), mload(add(pMem, pV3)))
g1_mulAccC(p, S1x, S1y, mload(add(pMem, pV4)))
g1_mulAccC(p, S2x, S2y, mload(add(pMem, pV5)))
}
function calculateE(pMem) {
let s := mod(sub(q, mload(add(pMem, pEval_r0))), q)
s := addmod(s, mulmod(calldataload(pEval_a), mload(add(pMem, pV1)), q), q)
s := addmod(s, mulmod(calldataload(pEval_b), mload(add(pMem, pV2)), q), q)
s := addmod(s, mulmod(calldataload(pEval_c), mload(add(pMem, pV3)), q), q)
s := addmod(s, mulmod(calldataload(pEval_s1), mload(add(pMem, pV4)), q), q)
s := addmod(s, mulmod(calldataload(pEval_s2), mload(add(pMem, pV5)), q), q)
s := addmod(s, mulmod(calldataload(pEval_zw), mload(add(pMem, pU)), q), q)
g1_mulSetC(add(pMem, pE), G1x, G1y, s)
}
function checkPairing(pMem) -> isOk {
let mIn := mload(0x40)
mstore(0x40, add(mIn, 576)) // [0..383] = pairing data, [384..447] = pWxi, [448..512] = pWxiw
let _pWxi := add(mIn, 384)
let _pWxiw := add(mIn, 448)
let _aux := add(mIn, 512)
g1_calldataSet(_pWxi, pWxi)
g1_calldataSet(_pWxiw, pWxiw)
// A1
g1_mulSet(mIn, _pWxiw, mload(add(pMem, pU)))
g1_acc(mIn, _pWxi)
mstore(add(mIn, 32), mod(sub(qf, mload(add(mIn, 32))), qf))
// [X]_2
mstore(add(mIn,64), X2x2)
mstore(add(mIn,96), X2x1)
mstore(add(mIn,128), X2y2)
mstore(add(mIn,160), X2y1)
// B1
g1_mulSet(add(mIn, 192), _pWxi, mload(add(pMem, pXi)))
let s := mulmod(mload(add(pMem, pU)), mload(add(pMem, pXi)), q)
s := mulmod(s, w1, q)
g1_mulSet(_aux, _pWxiw, s)
g1_acc(add(mIn, 192), _aux)
g1_acc(add(mIn, 192), add(pMem, pF))
mstore(add(pMem, add(pE, 32)), mod(sub(qf, mload(add(pMem, add(pE, 32)))), qf))
g1_acc(add(mIn, 192), add(pMem, pE))
// [1]_2
mstore(add(mIn,256), G2x2)
mstore(add(mIn,288), G2x1)
mstore(add(mIn,320), G2y2)
mstore(add(mIn,352), G2y1)
let success := staticcall(sub(gas(), 2000), 8, mIn, 384, mIn, 0x20)
isOk := and(success, mload(mIn))
}
let pMem := mload(0x40)
mstore(0x40, add(pMem, lastMem))
checkInput()
calculateChallenges(pMem, _pubSignals)
calculateLagrange(pMem)
calculatePI(pMem, _pubSignals)
calculateR0(pMem)
calculateD(pMem)
calculateF(pMem)
calculateE(pMem)
let isValid := checkPairing(pMem)
mstore(0x40, sub(pMem, lastMem))
mstore(0, isValid)
return(0,0x20)
}
}
}

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

@ -1,6 +1,6 @@
{
"name": "remix-project",
"version": "0.47.0-dev",
"version": "0.48.0-dev",
"license": "MIT",
"description": "Ethereum Remix Monorepo",
"main": "index.js",
@ -74,54 +74,12 @@
"minify": "uglifyjs --in-source-map inline --source-map-inline -c warnings=false",
"build:production": "NODE_ENV=production nx build remix-ide --configuration=production --skip-nx-cache",
"serve:production": "npx http-server ./dist/apps/remix-ide",
"install_webdriver": "bash ./apps/remix-ide-e2e/install-webdriver.sh",
"select_test": "bash apps/remix-ide-e2e/src/select_tests.sh",
"group_test": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/${npm_config_test}_group${npm_config_group}.test.js --env=${npm_config_env}",
"nightwatch_parallel": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome,firefox",
"nightwatch_local_firefox": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=firefox",
"nightwatch_local_chrome": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome",
"nightwatch_local_ballot": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot.test.js --env=chrome",
"nightwatch_local_ballot_0_4_14": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot_0_4_14.test.js --env=chrome",
"nightwatch_local_usingWorker": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/usingWebWorker.test.js --env=chrome",
"nightwatch_local_libraryDeployment": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/libraryDeployment.test.js --env=chrome",
"nightwatch_local_solidityImport": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityImport_*.test.js --env=chrome",
"nightwatch_local_recorder": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/recorder.test.js --env=chrome",
"nightwatch_local_transactionExecution": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/transactionExecution_*.test.js --env=chrome",
"nightwatch_local_staticAnalysis": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/staticAnalysis.test.js --env=chrome",
"nightwatch_local_signingMessage": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/signingMessage.test.js --env=chrome",
"nightwatch_local_specialFunctions": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/specialFunctions_*.test.js --env=chrome",
"nightwatch_local_solidityUnitTests": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityUnittests_*.test.js --env=chrome",
"nightwatch_local_remixd": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/remixd.test.js --env=chrome",
"nightwatch_local_terminal": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/terminal_*.test.js --env=chrome",
"nightwatch_local_gist": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/gist.test.js --env=chrome",
"nightwatch_local_workspace": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/workspace.test.js --env=chrome",
"nightwatch_local_defaultLayout": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/defaultLayout.test.js --env=chrome",
"nightwatch_local_pluginManager": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/pluginManager.test.js --env=chrome",
"nightwatch_local_publishContract": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/publishContract.test.js --env=chrome",
"nightwatch_local_generalSettings": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/generalSettings.test.js --env=chrome",
"nightwatch_local_fileExplorer": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileExplorer.test.js --env=chrome",
"nightwatch_local_debugger": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.test.js --env=chrome",
"nightwatch_local_editor": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/editor.test.js --env=chrome",
"nightwatch_local_importFromGithub": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/importFromGithub.test.js --env=chrome",
"nightwatch_local_compiler": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/compiler_api.test.js --env=chrome",
"nightwatch_local_txListener": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/txListener.test.js --env=chrome",
"nightwatch_local_fileManager": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileManager_api.test.js --env=chrome",
"nightwatch_local_runAndDeploy": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/runAndDeploy.js --env=chrome-runAndDeploy",
"nightwatch_local_url": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/url.test.js --env=chrome",
"nightwatch_local_verticalIconscontextmenu": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/verticalIconsPanel.test.js --env=chrome",
"nightwatch_local_pluginApi": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/plugin_api_*.js --env=chrome",
"nightwatch_local_migrate_filesystem": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/migrateFileSystem.test.js --env=chrome",
"nightwatch_local_proxy": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/proxy.test.js --env=chrome",
"nightwatch_local_stress_editor": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stressEditor.test.js --env=chromeDesktop",
"nightwatch_local_search": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/search.test.js --env=chromeDesktop",
"nightwatch_local_providers": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/providers.test.js --env=chromeDesktop",
"nightwatch_local_walkthrough": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/walkthrough.test.js --env=chromeDesktop",
"onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint",
"remixd": "nx build remixd && chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js --remix-ide http://127.0.0.1:8080",
"simulator": "nx build remix-simulator && chmod +x dist/libs/remix-simulator/bin/ethsim && dist/libs/remix-simulator/bin/ethsim start --rpc",
"selenium": "selenium-standalone start",
"selenium-install": "selenium-standalone install",
"sourcemap": "exorcist --root ../ apps/remix-ide/build/app.js.map > apps/remix-ide/build/app.js",
"test-browser": "npm-run-all -lpr selenium make-mock-compiler serve browsertest",
"watch": "watchify apps/remix-ide/src/index.js -dv -p browserify-reload -o apps/remix-ide/build/app.js --exclude solc",
"reinstall": "rm ./node-modules/ -rf && rm yarn.lock && rm ./build/ -rf && yarn install & yarn run build",
"ganache": "npx ganache",
@ -395,7 +353,6 @@
"react-refresh": "^0.14.0",
"request": "^2.83.0",
"rimraf": "^2.6.1",
"selenium-standalone": "^9.0.3",
"semver": "^7.4.0",
"solc": "^0.7.4",
"stream-browserify": "^3.0.0",

@ -1,10 +1,10 @@
{
"version": "v0.46.0",
"version": "v0.47.0",
"title": "RELEASE HIGHLIGHTS",
"highlight1": "Remix VM (Cancun) added with the functionalities of cancun fork",
"highlight2": "Latest Solidity compiler version set to 0.8.25 with cancun as default EVM version",
"highlight3": "",
"highlight1": "Contract pinning enabled for Remix VMs too",
"highlight2": "Dapp draft plugin added to edit & deploy a DApp",
"highlight3": "AI tools integrated using Solcoder",
"highlight4": "",
"more": "Read More",
"moreLink": "https://medium.com/remix-ide/remix-release-v0-46-0-f90a4948fff0"
"moreLink": "https://medium.com/remix-ide/remix-release-v0-47-0-d52f3dc21886"
}

@ -6349,19 +6349,6 @@
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
"@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"
"@redux-saga/core@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.3.0.tgz#2ce08b73d407fc6ea9e7f7d83d2e97d981a3a8b8"
@ -7048,11 +7035,6 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
"@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==
"@trufflesuite/bigint-buffer@1.1.10":
version "1.1.10"
resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz#a1d9ca22d3cad1a138b78baaf15543637a3e1692"
@ -8825,10 +8807,10 @@ agent-base@6, agent-base@^6.0.2:
dependencies:
debug "4"
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==
agent-base@^7.0.2, agent-base@^7.1.0:
version "7.1.1"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317"
integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==
dependencies:
debug "^4.3.4"
@ -9469,13 +9451,6 @@ ast-types-flow@^0.0.7:
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==
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"
astral-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
@ -9619,7 +9594,7 @@ axios-debug-log@^1.0.0:
"@types/debug" "^4.0.0"
debug "^4.0.0"
axios@*, axios@1.6.0, axios@^1.0.0, axios@^1.4.0:
axios@*, axios@1.6.0, axios@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102"
integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==
@ -10448,11 +10423,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==
batch@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
@ -13308,11 +13278,6 @@ data-uri-to-buffer@^3.0.1:
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636"
integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==
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==
dataloader@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.2.2.tgz#216dc509b5abe39d43a9b9d97e6e5e473dfbe3e0"
@ -13627,15 +13592,6 @@ defu@^6.1.3, defu@^6.1.4:
resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479"
integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==
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"
@ -14687,17 +14643,6 @@ escodegen@^1.8.1:
optionalDependencies:
source-map "~0.6.1"
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"
eslint-config-prettier@^8.5.0:
version "8.5.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1"
@ -16679,16 +16624,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"
@ -17098,23 +17033,6 @@ got@^11.7.0, got@^11.8.5:
p-cancelable "^2.0.0"
responselike "^2.0.0"
got@^11.8.2:
version "11.8.3"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770"
integrity sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==
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@^6.7.1:
version "6.7.1"
resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
@ -17800,9 +17718,9 @@ http-proxy-agent@^5.0.0:
debug "4"
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==
version "7.0.2"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e"
integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==
dependencies:
agent-base "^7.1.0"
debug "^4.3.4"
@ -17907,9 +17825,9 @@ https-proxy-agent@^5.0.0:
debug "4"
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==
version "7.0.4"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz#8e97b841a029ad8ddc8731f26595bad868cb4168"
integrity sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==
dependencies:
agent-base "^7.0.2"
debug "4"
@ -18365,11 +18283,6 @@ ip@1.1.5:
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
ip@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48"
integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==
ip@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
@ -18976,11 +18889,6 @@ is-plain-object@^5.0.0:
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
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-posix-bracket@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
@ -21032,11 +20940,6 @@ 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 sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@ -21260,7 +21163,7 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
lru-cache@^7.14.1, lru-cache@^7.7.1:
lru-cache@^7.7.1:
version "7.18.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89"
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
@ -22471,11 +22374,6 @@ mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
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"
@ -22962,11 +22860,6 @@ neo-async@^2.6.0, neo-async@^2.6.2:
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
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==
next-tick@1, next-tick@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
@ -24432,29 +24325,6 @@ p-waterfall@^1.0.0:
dependencies:
p-reduce "^1.0.0"
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-hash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-3.0.0.tgz#50183f2d36c9e3e528ea0a8605dff57ce976f88e"
@ -25691,20 +25561,6 @@ proxy-addr@~2.0.7:
forwarded "0.2.0"
ipaddr.js "1.9.1"
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-compare@2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/proxy-compare/-/proxy-compare-2.5.1.tgz#17818e33d1653fbac8c2ec31406bce8a2966f600"
@ -27653,28 +27509,6 @@ select-hose@^2.0.0:
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
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"
@ -28230,16 +28064,7 @@ socks-proxy-agent@^7.0.0:
debug "^4.3.3"
socks "^2.6.2"
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.6.2, socks@^2.7.1:
socks@^2.6.2:
version "2.7.1"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55"
integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==
@ -29389,7 +29214,7 @@ tar-fs@2.1.1, tar-fs@^2.0.0:
pump "^3.0.0"
tar-stream "^2.1.4"
tar-fs@3.0.4, tar-fs@^3.0.4:
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==
@ -29403,15 +29228,6 @@ tar-js@^0.3.0:
resolved "https://registry.yarnpkg.com/tar-js/-/tar-js-0.3.0.tgz#6949aabfb0ba18bb1562ae51a439fd0f30183a17"
integrity sha1-aUmqv7C6GLsVYq5RpDn9DzAYOhc=
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"
tar-stream@^2.1.0, tar-stream@^2.1.4, tar-stream@~2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
@ -29423,6 +29239,15 @@ tar-stream@^2.1.0, tar-stream@^2.1.4, tar-stream@~2.2.0:
inherits "^2.0.3"
readable-stream "^3.1.1"
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"
tar@^2.0.0, tar@~2.2.1:
version "2.2.2"
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40"
@ -29983,11 +29808,6 @@ tslib@^2.0.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
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==
tslib@^2.0.3, tslib@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
@ -30398,9 +30218,9 @@ undici-types@~5.26.4:
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
undici@^5.14.0:
version "5.28.3"
resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.3.tgz#a731e0eff2c3fcfd41c1169a869062be222d1e5b"
integrity sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==
version "5.28.4"
resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068"
integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==
dependencies:
"@fastify/busboy" "^2.0.0"
@ -32152,19 +31972,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"
yargs@^10.0.3:
version "10.0.3"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae"

Loading…
Cancel
Save