diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index df2c0433b1..7485ee7c82 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -81,6 +81,12 @@ jobs: with: platforms: linux/amd64,linux/arm64/v8 + sync_envs_docs: + name: Sync ENV variables docs + uses: './.github/workflows/sync-envs-docs.yml' + needs: publish_image + secrets: inherit + # Temporary disable this step because it is broken # There is an issue with building web3modal deps upload_source_maps: diff --git a/.github/workflows/sync-envs-docs.yml b/.github/workflows/sync-envs-docs.yml new file mode 100644 index 0000000000..4e034dd9eb --- /dev/null +++ b/.github/workflows/sync-envs-docs.yml @@ -0,0 +1,40 @@ +name: Sync ENV variables docs + +on: + workflow_dispatch: + +jobs: + run: + name: Run + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Copy main ENV file to Blockscout Docs repository + uses: dmnemec/copy_file_to_another_repo_action@main + env: + API_TOKEN_GITHUB: ${{ secrets.GITHIB_BOT_TOKEN }} + with: + source_file: 'docs/ENVS.md' + destination_repo: 'blockscout/docs' + destination_folder: 'setup/env-variables/frontend-common-envs' + rename: 'envs.md' + destination_branch: 'master' + user_email: 'bot@blockscout.com' + user_name: 'blockscout-bot' + use_rsync: true + + - name: Copy deprecated ENV file to Blockscout Docs repository + uses: dmnemec/copy_file_to_another_repo_action@main + env: + API_TOKEN_GITHUB: ${{ secrets.GITHIB_BOT_TOKEN }} + with: + source_file: 'docs/DEPRECATED_ENVS.md' + destination_repo: 'blockscout/docs' + destination_folder: 'setup/env-variables/frontend-common-envs' + rename: 'deprecated-envs.md' + destination_branch: 'master' + user_email: 'bot@blockscout.com' + user_name: 'blockscout-bot' + use_rsync: true diff --git a/configs/app/features/multichainButton.ts b/configs/app/features/multichainButton.ts index 47b1433d05..923a16bd27 100644 --- a/configs/app/features/multichainButton.ts +++ b/configs/app/features/multichainButton.ts @@ -1,22 +1,24 @@ import type { Feature } from './types'; -import type { MultichainProviderConfig } from 'types/client/multichainProviderConfig'; +import type { MultichainProviderConfig, MultichainProviderConfigParsed } from 'types/client/multichainProviderConfig'; import { getEnvValue, parseEnvJson } from '../utils'; import marketplace from './marketplace'; -const value = parseEnvJson(getEnvValue('NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG')); +const value = parseEnvJson>(getEnvValue('NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG')); const title = 'Multichain balance'; -const config: Feature<{name: string; logoUrl?: string; urlTemplate: string; dappId?: string }> = (() => { +const config: Feature<{ providers: Array }> = (() => { if (value) { return Object.freeze({ title, isEnabled: true, - name: value.name, - logoUrl: value.logo, - urlTemplate: value.url_template, - dappId: marketplace.isEnabled ? value.dapp_id : undefined, + providers: value.map((provider) => ({ + name: provider.name, + logoUrl: provider.logo, + urlTemplate: provider.url_template, + dappId: marketplace.isEnabled ? provider.dapp_id : undefined, + })), }); } diff --git a/configs/envs/.env.base b/configs/envs/.env.base index 2c9cdf6699..9003326a81 100644 --- a/configs/envs/.env.base +++ b/configs/envs/.env.base @@ -38,7 +38,7 @@ NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6u NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com NEXT_PUBLIC_METASUITES_ENABLED=true -NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG={'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'} +NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}] NEXT_PUBLIC_NAME_SERVICE_API_HOST=https://bens.services.blockscout.com NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/apps'] NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18 diff --git a/configs/envs/.env.eth b/configs/envs/.env.eth index 0ea799c9a3..42a4639b87 100644 --- a/configs/envs/.env.eth +++ b/configs/envs/.env.eth @@ -39,7 +39,7 @@ NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKj NEXT_PUBLIC_MARKETPLACE_RATING_AIRTABLE_BASE_ID=appGkvtmKI7fXE4Vs NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com NEXT_PUBLIC_METASUITES_ENABLED=true -NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG={'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'} +NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}, {'name': 'zerion2', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}] NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG={'name': 'Need gas?', 'dapp_id': 'smol-refuel', 'url_template': 'https://smolrefuel.com/?outboundChain={chainId}&partner=blockscout&utm_source=blockscout&utm_medium=address&disableBridges=true', 'logo': 'https://blockscout-content.s3.amazonaws.com/smolrefuel-logo-action-button.png'} NEXT_PUBLIC_NAME_SERVICE_API_HOST=https://bens.services.blockscout.com NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/apps'] diff --git a/configs/envs/.env.eth_sepolia b/configs/envs/.env.eth_sepolia index 01698d12c4..9dbc3b8d11 100644 --- a/configs/envs/.env.eth_sepolia +++ b/configs/envs/.env.eth_sepolia @@ -38,7 +38,7 @@ NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6u NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com NEXT_PUBLIC_METASUITES_ENABLED=true -NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG={'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'} +NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}] NEXT_PUBLIC_NAME_SERVICE_API_HOST=https://bens.services.blockscout.com NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/apps'] NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18 diff --git a/configs/envs/.env.gnosis b/configs/envs/.env.gnosis index 60e7c3c161..dead77d742 100644 --- a/configs/envs/.env.gnosis +++ b/configs/envs/.env.gnosis @@ -45,7 +45,7 @@ NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKj NEXT_PUBLIC_MARKETPLACE_GRAPH_LINKS_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/refs/heads/marketplace-graph-test/test-configs/marketplace-graph-links.json NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com NEXT_PUBLIC_METASUITES_ENABLED=true -NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG={'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'} +NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}] NEXT_PUBLIC_NAME_SERVICE_API_HOST=https://bens.services.blockscout.com NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/apps'] NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18 diff --git a/configs/envs/.env.main b/configs/envs/.env.main index d33f7ec621..e9d31eedb2 100644 --- a/configs/envs/.env.main +++ b/configs/envs/.env.main @@ -39,7 +39,7 @@ NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6u NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata-test.k8s-dev.blockscout.com NEXT_PUBLIC_METASUITES_ENABLED=true -NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG={'name': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'} +NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}] NEXT_PUBLIC_NAME_SERVICE_API_HOST=https://bens-rs-test.k8s-dev.blockscout.com NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/blocks','/apps'] NEXT_PUBLIC_NAVIGATION_LAYOUT=horizontal diff --git a/configs/envs/.env.optimism b/configs/envs/.env.optimism index f23300e95f..45f46dc01e 100644 --- a/configs/envs/.env.optimism +++ b/configs/envs/.env.optimism @@ -39,7 +39,7 @@ NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6u NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com NEXT_PUBLIC_METASUITES_ENABLED=true -NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG={'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'} +NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}] NEXT_PUBLIC_NAME_SERVICE_API_HOST=https://bens.services.blockscout.com NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/apps'] NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18 diff --git a/configs/envs/.env.zksync b/configs/envs/.env.zksync index 3ae765711d..0638d13b80 100644 --- a/configs/envs/.env.zksync +++ b/configs/envs/.env.zksync @@ -27,7 +27,7 @@ NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true NEXT_PUBLIC_LOGOUT_URL=https://zksync.us.auth0.com/v2/logout NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com NEXT_PUBLIC_METASUITES_ENABLED=true -NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG={'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'} +NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}] NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18 NEXT_PUBLIC_NETWORK_CURRENCY_NAME=ETH NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=ETH diff --git a/configs/envs/.env.zora b/configs/envs/.env.zora index 1ad405ea6b..de5a551bd1 100644 --- a/configs/envs/.env.zora +++ b/configs/envs/.env.zora @@ -56,5 +56,5 @@ NEXT_PUBLIC_ROLLUP_TYPE=optimistic NEXT_PUBLIC_STATS_API_HOST=https://stats-l2-zora-mainnet.k8s-prod-1.blockscout.com NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com -NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG={'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'} -NEXT_PUBLIC_ADDRESS_USERNAME_TAG={'api_url_template': 'https://api.zora.co/discover/user/{address}', 'tag_link_template': 'httpszora.co/{username}', 'tag_icon': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/zora.svg', 'tag_bg_color': 'rgba(0,0,0)', 'tag_text_color': 'rgba(255,255,255)'} \ No newline at end of file +NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'dapp_id': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}] +NEXT_PUBLIC_ADDRESS_USERNAME_TAG={'api_url_template': 'https://api.zora.co/discover/user/{address}', 'tag_link_template': 'httpszora.co/{username}', 'tag_icon': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/zora.svg', 'tag_bg_color': 'rgba(0,0,0)', 'tag_text_color': 'rgba(255,255,255)'} diff --git a/deploy/scripts/entrypoint.sh b/deploy/scripts/entrypoint.sh index 298303c7a0..ac1f91d6c5 100755 --- a/deploy/scripts/entrypoint.sh +++ b/deploy/scripts/entrypoint.sh @@ -39,9 +39,14 @@ export_envs_from_preset ./download_assets.sh ./public/assets/configs # Check run-time ENVs values -./validate_envs.sh -if [ $? -ne 0 ]; then - exit 1 +if [ "$SKIP_ENVS_VALIDATION" != "true" ]; then + ./validate_envs.sh + if [ $? -ne 0 ]; then + exit 1 + fi +else + echo "😱 Skipping ENVs validation." + echo fi # Generate favicons bundle diff --git a/deploy/tools/affected-tests/yarn.lock b/deploy/tools/affected-tests/yarn.lock index 385918d425..bd755eda2b 100644 --- a/deploy/tools/affected-tests/yarn.lock +++ b/deploy/tools/affected-tests/yarn.lock @@ -90,7 +90,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.2: +braces@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== @@ -441,11 +441,11 @@ merge2@^1.3.0, merge2@^1.4.1: integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" minimatch@^3.1.1: @@ -582,9 +582,9 @@ requirejs-config-file@^4.0.0: stringify-object "^3.2.1" requirejs@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9" - integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg== + version "2.3.7" + resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.7.tgz#0b22032e51a967900e0ae9f32762c23a87036bd0" + integrity "sha1-CyIDLlGpZ5AOCunzJ2LCOocDa9A= sha512-DouTG8T1WanGok6Qjg2SXuCMzszOo0eHeH9hDZ5Y4x8Je+9JB38HdTLT4/VA8OaUhBa0JPVHJ0pyBkM1z+pDsw==" resolve-dependency-path@^3.0.2: version "3.0.2" diff --git a/deploy/tools/envs-validator/schema.ts b/deploy/tools/envs-validator/schema.ts index cd35ed2299..426f0cdc84 100644 --- a/deploy/tools/envs-validator/schema.ts +++ b/deploy/tools/envs-validator/schema.ts @@ -530,6 +530,13 @@ const deFiDropdownItemSchema: yup.ObjectSchema = yup return Boolean(value.dappId) || Boolean(value.url); }) as yup.ObjectSchema; +const multichainProviderConfigSchema: yup.ObjectSchema = yup.object({ + name: yup.string().required(), + url_template: yup.string().required(), + logo: yup.string().required(), + dapp_id: yup.string(), +}); + const schema = yup .object() .noUnknown(true, (params) => { @@ -768,18 +775,10 @@ const schema = yup NEXT_PUBLIC_HAS_USER_OPS: yup.boolean(), NEXT_PUBLIC_METASUITES_ENABLED: yup.boolean(), NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG: yup - .mixed() - .test('shape', 'Invalid schema were provided for NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG, it should have name and url template', (data) => { - const isUndefined = data === undefined; - const valueSchema = yup.object().transform(replaceQuotes).json().shape({ - name: yup.string().required(), - url_template: yup.string().required(), - logo: yup.string(), - dapp_id: yup.string(), - }); - - return isUndefined || valueSchema.isValidSync(data); - }), + .array() + .transform(replaceQuotes) + .json() + .of(multichainProviderConfigSchema), NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG: yup .mixed() .test('shape', 'Invalid schema were provided for NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG, it should have name and url template', (data) => { diff --git a/deploy/tools/envs-validator/test/.env.base b/deploy/tools/envs-validator/test/.env.base index 09db6ed2f4..cc0c5869c6 100644 --- a/deploy/tools/envs-validator/test/.env.base +++ b/deploy/tools/envs-validator/test/.env.base @@ -83,6 +83,6 @@ NEXT_PUBLIC_WEB3_DISABLE_ADD_TOKEN_TO_WALLET=false NEXT_PUBLIC_WEB3_WALLETS=['coinbase','metamask','token_pocket'] NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE=stability NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swap','icon':'swap','dappId':'uniswap'},{'text':'Payment link','icon':'payment_link','url':'https://example.com'}] -NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG={'name': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'} +NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}] NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG={'name': 'Need gas?', 'dapp_id': 'smol-refuel', 'url_template': 'https://smolrefuel.com/?outboundChain={chainId}&partner=blockscout&utm_source=blockscout&utm_medium=address&disableBridges=true', 'logo': 'https://blockscout-content.s3.amazonaws.com/smolrefuel-logo-action-button.png'} NEXT_PUBLIC_SAVE_ON_GAS_ENABLED=true diff --git a/deploy/tools/envs-validator/yarn.lock b/deploy/tools/envs-validator/yarn.lock index 6ea4de04cf..8259f31c56 100644 --- a/deploy/tools/envs-validator/yarn.lock +++ b/deploy/tools/envs-validator/yarn.lock @@ -21,6 +21,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" @@ -44,7 +49,20 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.20": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": version "0.3.18" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== @@ -52,28 +70,12 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.44.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.0.tgz#55818eabb376e2272f77fbf5c96c43137c3c1e53" - integrity sha512-gsF+c/0XOguWgaOgvFs+xnnRqt9GwgTvIks36WpE6ueeI4KCEHHd8K/CKHqhOqrJKsYH8m27kRzQEvWXAwXUTw== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" +"@types/estree@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" - integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== - -"@types/json-schema@*", "@types/json-schema@^7.0.8": +"@types/json-schema@^7.0.8": version "7.0.12" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== @@ -83,10 +85,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== -"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" - integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== dependencies: "@webassemblyjs/helper-numbers" "1.11.6" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" @@ -101,10 +103,10 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-buffer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" - integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== "@webassemblyjs/helper-numbers@1.11.6": version "1.11.6" @@ -120,15 +122,15 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" - integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/ieee754@1.11.6": version "1.11.6" @@ -149,59 +151,59 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== -"@webassemblyjs/wasm-edit@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" - integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-opt" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" - "@webassemblyjs/wast-printer" "1.11.6" - -"@webassemblyjs/wasm-gen@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" - integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== - dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/ieee754" "1.11.6" "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wasm-opt@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" - integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" -"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" - integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/ast" "1.12.1" "@webassemblyjs/helper-api-error" "1.11.6" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/ieee754" "1.11.6" "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wast-printer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" - integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/ast" "1.12.1" "@xtuc/long" "4.2.2" "@webpack-cli/configtest@^2.1.1": @@ -229,10 +231,10 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -acorn-import-assertions@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" - integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== acorn@^8.7.1, acorn@^8.8.2: version "8.10.0" @@ -261,32 +263,32 @@ ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -braces@^3.0.2: +braces@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" -browserslist@^4.14.5: - version "4.21.9" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" - integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== +browserslist@^4.21.10: + version "4.24.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" + integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== dependencies: - caniuse-lite "^1.0.30001503" - electron-to-chromium "^1.4.431" - node-releases "^2.0.12" - update-browserslist-db "^1.0.11" + caniuse-lite "^1.0.30001669" + electron-to-chromium "^1.5.41" + node-releases "^2.0.18" + update-browserslist-db "^1.1.1" buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -caniuse-lite@^1.0.30001503: - version "1.0.30001517" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz#90fabae294215c3495807eb24fc809e11dc2f0a8" - integrity sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA== +caniuse-lite@^1.0.30001669: + version "1.0.30001673" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz#5aa291557af1c71340e809987367410aab7a5a9e" + integrity sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw== chalk@^4.1.0: version "4.1.2" @@ -366,12 +368,12 @@ dotenv@^16.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== -electron-to-chromium@^1.4.431: - version "1.4.467" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.467.tgz#b0660bf644baff7eedea33b8c742fb53ec60e3c2" - integrity sha512-2qI70O+rR4poYeF2grcuS/bCps5KJh6y1jtZMDDEteyKJQrzLOEhFyXCLcHW6DTBjKjWkk26JhWoAi+Ux9A0fg== +electron-to-chromium@^1.5.41: + version "1.5.47" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz#ef0751bc19b28be8ee44cd8405309de3bf3b20c7" + integrity sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ== -enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0, enhanced-resolve@^5.7.0: +enhanced-resolve@^5.0.0, enhanced-resolve@^5.7.0: version "5.15.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== @@ -379,6 +381,14 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0, enhanced-resolve@^5.7.0: graceful-fs "^4.2.4" tapable "^2.2.0" +enhanced-resolve@^5.17.1: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + envinfo@^7.7.3: version "7.10.0" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" @@ -389,10 +399,10 @@ es-module-lexer@^1.2.1: resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f" integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA== -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== eslint-scope@5.1.1: version "5.1.1" @@ -464,7 +474,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -577,11 +587,11 @@ merge-stream@^2.0.0: integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== micromatch@^4.0.0: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.52.0: @@ -606,10 +616,10 @@ 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== -node-releases@^2.0.12: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== p-limit@^2.2.0: version "2.3.0" @@ -645,10 +655,10 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.3.1: version "2.3.1" @@ -796,21 +806,21 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.3.7: - version "5.3.9" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" - integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== +terser-webpack-plugin@^5.3.10: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== dependencies: - "@jridgewell/trace-mapping" "^0.3.17" + "@jridgewell/trace-mapping" "^0.3.20" jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.1" - terser "^5.16.8" + terser "^5.26.0" -terser@^5.16.8: - version "5.19.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.2.tgz#bdb8017a9a4a8de4663a7983f45c506534f9234e" - integrity sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA== +terser@^5.26.0: + version "5.36.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.36.0.tgz#8b0dbed459ac40ff7b4c9fd5a3a2029de105180e" + integrity sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -867,13 +877,13 @@ type-fest@^2.19.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== -update-browserslist-db@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" - integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== +update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" + escalade "^3.2.0" + picocolors "^1.1.0" uri-js@^4.2.2: version "4.4.1" @@ -882,10 +892,10 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== +watchpack@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" + integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -923,33 +933,32 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.88.2: - version "5.88.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" - integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.0" - "@webassemblyjs/ast" "^1.11.5" - "@webassemblyjs/wasm-edit" "^1.11.5" - "@webassemblyjs/wasm-parser" "^1.11.5" + version "5.95.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.95.0.tgz#8fd8c454fa60dad186fbe36c400a55848307b4c0" + integrity sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q== + dependencies: + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" - acorn-import-assertions "^1.9.0" - browserslist "^4.14.5" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.15.0" + enhanced-resolve "^5.17.1" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.3.7" - watchpack "^2.4.0" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" which@^2.0.1: diff --git a/deploy/tools/feature-reporter/yarn.lock b/deploy/tools/feature-reporter/yarn.lock index 502e97507e..783abddc02 100644 --- a/deploy/tools/feature-reporter/yarn.lock +++ b/deploy/tools/feature-reporter/yarn.lock @@ -39,7 +39,15 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.20": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": version "0.3.19" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== @@ -68,28 +76,12 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" +"@types/estree@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity "sha1-Yo7/7q4gZKG055946B2Ht+X8e1A= sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" -"@types/eslint@*": - version "8.44.2" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.2.tgz#0d21c505f98a89b8dd4d37fa162b09da6089199a" - integrity sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" - integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== - -"@types/json-schema@*", "@types/json-schema@^7.0.8": +"@types/json-schema@^7.0.8": version "7.0.12" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== @@ -99,10 +91,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.8.tgz#b5dda19adaa473a9bf0ab5cbd8f30ec7d43f5c85" integrity sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg== -"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" - integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== dependencies: "@webassemblyjs/helper-numbers" "1.11.6" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" @@ -117,10 +109,10 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-buffer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" - integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== "@webassemblyjs/helper-numbers@1.11.6": version "1.11.6" @@ -136,15 +128,15 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" - integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/ieee754@1.11.6": version "1.11.6" @@ -165,59 +157,59 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== -"@webassemblyjs/wasm-edit@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" - integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-opt" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" - "@webassemblyjs/wast-printer" "1.11.6" - -"@webassemblyjs/wasm-gen@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" - integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== - dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/ieee754" "1.11.6" "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wasm-opt@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" - integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" -"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" - integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/ast" "1.12.1" "@webassemblyjs/helper-api-error" "1.11.6" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/ieee754" "1.11.6" "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wast-printer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" - integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/ast" "1.12.1" "@xtuc/long" "4.2.2" "@webpack-cli/configtest@^2.1.1": @@ -245,10 +237,10 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -acorn-import-assertions@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" - integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== acorn@^8.7.1, acorn@^8.8.2: version "8.10.0" @@ -288,32 +280,32 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -braces@^3.0.2, braces@~3.0.2: +braces@^3.0.3, braces@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" -browserslist@^4.14.5: - version "4.21.10" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" - integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== +browserslist@^4.21.10: + version "4.24.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" + integrity "sha1-9YRbyRBp29Ve6J+vmCLh2IXRZYA= sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==" dependencies: - caniuse-lite "^1.0.30001517" - electron-to-chromium "^1.4.477" - node-releases "^2.0.13" - update-browserslist-db "^1.0.11" + caniuse-lite "^1.0.30001669" + electron-to-chromium "^1.5.41" + node-releases "^2.0.18" + update-browserslist-db "^1.1.1" buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -caniuse-lite@^1.0.30001517: - version "1.0.30001519" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" - integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== +caniuse-lite@^1.0.30001669: + version "1.0.30001673" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz#5aa291557af1c71340e809987367410aab7a5a9e" + integrity "sha1-WqKRVXrxxxNA6AmYc2dBCqt6Wp4= sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==" chokidar@^3.5.3: version "3.5.3" @@ -400,15 +392,15 @@ dotenv@^16.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== -electron-to-chromium@^1.4.477: - version "1.4.487" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.487.tgz#e2ef8b15f2791bf68fa6f38f2656f1a551d360ae" - integrity sha512-XbCRs/34l31np/p33m+5tdBrdXu9jJkZxSbNxj5I0H1KtV2ZMSB+i/HYqDiRzHaFx2T5EdytjoBRe8QRJE2vQg== +electron-to-chromium@^1.5.41: + version "1.5.47" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz#ef0751bc19b28be8ee44cd8405309de3bf3b20c7" + integrity "sha1-7wdRvBmyi+juRM2EBTCd4787IMc= sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==" -enhanced-resolve@^5.15.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== +enhanced-resolve@^5.17.1: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -423,10 +415,10 @@ es-module-lexer@^1.2.1: resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f" integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA== -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== eslint-scope@5.1.1: version "5.1.1" @@ -540,7 +532,7 @@ globby@^11.0.4: merge2 "^1.4.1" slash "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -670,11 +662,11 @@ merge2@^1.3.0, merge2@^1.4.1: integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.52.0: @@ -704,10 +696,10 @@ 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== -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -753,10 +745,10 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity "sha1-PTIa8+q5ObCDyPkpodEs2oHCa2s= sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" @@ -921,21 +913,21 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.3.7: - version "5.3.9" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" - integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== +terser-webpack-plugin@^5.3.10: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== dependencies: - "@jridgewell/trace-mapping" "^0.3.17" + "@jridgewell/trace-mapping" "^0.3.20" jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.1" - terser "^5.16.8" + terser "^5.26.0" -terser@^5.16.8: - version "5.19.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.2.tgz#bdb8017a9a4a8de4663a7983f45c506534f9234e" - integrity sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA== +terser@^5.26.0: + version "5.36.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.36.0.tgz#8b0dbed459ac40ff7b4c9fd5a3a2029de105180e" + integrity "sha1-iw2+1FmsQP97TJ/Vo6ICneEFGA4= sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==" dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -971,13 +963,13 @@ typescript@5.1: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== -update-browserslist-db@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" - integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== +update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity "sha1-gIRvuh156CVH+2YfjRQeCUV1X+U= sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==" dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" + escalade "^3.2.0" + picocolors "^1.1.0" uri-js@^4.2.2: version "4.4.1" @@ -986,10 +978,10 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== +watchpack@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" + integrity "sha1-L+6u1nQS58MxhOWnnKc4+9OFZNo= sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==" dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -1027,33 +1019,32 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.88.2: - version "5.88.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" - integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.0" - "@webassemblyjs/ast" "^1.11.5" - "@webassemblyjs/wasm-edit" "^1.11.5" - "@webassemblyjs/wasm-parser" "^1.11.5" + version "5.95.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.95.0.tgz#8fd8c454fa60dad186fbe36c400a55848307b4c0" + integrity "sha1-j9jEVPpg2tGG++NsQApVhIMHtMA= sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==" + dependencies: + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" - acorn-import-assertions "^1.9.0" - browserslist "^4.14.5" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.15.0" + enhanced-resolve "^5.17.1" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.3.7" - watchpack "^2.4.0" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" which@^2.0.1: diff --git a/docs/ENVS.md b/docs/ENVS.md index b5e2d7faa2..79b7ff4353 100644 --- a/docs/ENVS.md +++ b/docs/ENVS.md @@ -219,6 +219,7 @@ Settings for meta tags, OG tags and SEO ##### Block fields list | Id | Description | | --- | --- | +| `base_fee` | Base fee | | `burnt_fees` | Burnt fees | | `total_reward` | Total block reward | | `nonce` | Block nonce | @@ -747,7 +748,7 @@ If the feature is enabled, a Multichain balance button will be displayed on the | Variable | Type| Description | Compulsoriness | Default value | Example value | Version | | --- | --- | --- | --- | --- | --- | --- | -| NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG | `{ name: string; url_template: string; dapp_id?: string; logo?: string }` | Multichain portfolio application config See [below](#multichain-button-configuration-properties) | - | - | `{ name: 'zerion', url_template: 'https://app.zerion.io/{address}/overview', logo: 'https://example.com/icon.svg'` | v1.31.0+ | +| NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG | `[{ name: string; url_template: string; dapp_id?: string; logo: string }]` | Multichain portfolio application config See [below](#multichain-button-configuration-properties) | - | - | `[{ name: 'zerion', url_template: 'https://app.zerion.io/{address}/overview', logo: 'https://example.com/icon.svg'}]` | v1.31.0+ |   diff --git a/lib/api/resources.ts b/lib/api/resources.ts index c8cff1945c..6b58cd6807 100644 --- a/lib/api/resources.ts +++ b/lib/api/resources.ts @@ -67,6 +67,8 @@ import type { SmartContract, SmartContractVerificationConfigRaw, SmartContractSecurityAudits, + SmartContractMudSystemsResponse, + SmartContractMudSystemInfo, } from 'types/api/contract'; import type { VerifiedContractsResponse, VerifiedContractsFilters, VerifiedContractsCounters } from 'types/api/contracts'; import type { @@ -784,6 +786,16 @@ export const RESOURCES = { pathParams: [ 'hash' as const, 'table_id' as const, 'record_id' as const ], }, + contract_mud_systems: { + path: '/api/v2/mud/worlds/:hash/systems', + pathParams: [ 'hash' as const ], + }, + + contract_mud_system_info: { + path: '/api/v2/mud/worlds/:hash/systems/:system_address', + pathParams: [ 'hash' as const, 'system_address' as const ], + }, + // arbitrum L2 arbitrum_l2_messages: { path: '/api/v2/arbitrum/messages/:direction', @@ -1212,6 +1224,8 @@ Q extends 'address_mud_tables' ? AddressMudTables : Q extends 'address_mud_tables_count' ? number : Q extends 'address_mud_records' ? AddressMudRecords : Q extends 'address_mud_record' ? AddressMudRecord : +Q extends 'contract_mud_systems' ? SmartContractMudSystemsResponse : +Q extends 'contract_mud_system_info' ? SmartContractMudSystemInfo : Q extends 'address_epoch_rewards' ? AddressEpochRewardsResponse : Q extends 'withdrawals' ? WithdrawalsResponse : Q extends 'withdrawals_counters' ? WithdrawalsCounters : diff --git a/lib/validations/address.ts b/lib/validations/address.ts deleted file mode 100644 index cfca644c41..0000000000 --- a/lib/validations/address.ts +++ /dev/null @@ -1,5 +0,0 @@ -// maybe it depends on the network?? - -export const ADDRESS_REGEXP = /^0x[a-fA-F\d]{40}$/; - -export const ADDRESS_LENGTH = 42; diff --git a/lib/validations/url.ts b/lib/validations/url.ts deleted file mode 100644 index b4b30d4e05..0000000000 --- a/lib/validations/url.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const validator = (value: string | undefined) => { - if (!value) { - return true; - } - - try { - new URL(value); - return true; - } catch (error) { - return 'Incorrect URL'; - } -}; diff --git a/package.json b/package.json index eefd69a6e1..06016e4572 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "react-device-detect": "^2.2.3", "react-dom": "18.2.0", "react-google-recaptcha-v3": "1.10.1", - "react-hook-form": "^7.33.1", + "react-hook-form": "7.52.1", "react-identicons": "^1.2.5", "react-intersection-observer": "^9.5.2", "react-jazzicon": "^1.0.4", diff --git a/stubs/contract.ts b/stubs/contract.ts index 67219f8a5b..92b86ac2e7 100644 --- a/stubs/contract.ts +++ b/stubs/contract.ts @@ -1,9 +1,9 @@ -import type { SmartContract } from 'types/api/contract'; +import type { SmartContract, SmartContractMudSystemsResponse } from 'types/api/contract'; import type { VerifiedContract, VerifiedContractsCounters } from 'types/api/contracts'; import type { SolidityScanReport } from 'lib/solidityScan/schema'; -import { ADDRESS_PARAMS } from './addressParams'; +import { ADDRESS_PARAMS, ADDRESS_HASH } from './addressParams'; export const CONTRACT_CODE_UNVERIFIED = { creation_bytecode: '0x60806040526e', @@ -46,6 +46,7 @@ export const CONTRACT_CODE_VERIFIED = { remappings: [], }, compiler_version: 'v0.8.7+commit.e28d00a7', + constructor_args: '0000000000000000000000005c7bcd6e7de5423a257d81b442095a1a6ced35c5000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', creation_bytecode: '0x6080604052348', deployed_bytecode: '0x60806040', evm_version: 'london', @@ -98,3 +99,12 @@ export const SOLIDITY_SCAN_REPORT: SolidityScanReport = { scanner_reference_url: 'https://solidityscan.com/quickscan/0xc1EF7811FF2ebFB74F80ed7423f2AdAA37454be2/blockscout/eth-goerli?ref=blockscout', }, }; + +export const MUD_SYSTEMS: SmartContractMudSystemsResponse = { + items: [ + { + name: 'sy.AccessManagement', + address: ADDRESS_HASH, + }, + ], +}; diff --git a/theme/components/Button/Button.pw.tsx b/theme/components/Button/Button.pw.tsx index e8b15075a7..a0c400120f 100644 --- a/theme/components/Button/Button.pw.tsx +++ b/theme/components/Button/Button.pw.tsx @@ -15,6 +15,7 @@ test.use({ viewport: { width: 150, height: 350 } }); { variant: 'subtle', colorScheme: 'gray', states: [ 'default', 'hovered' ], withDarkMode: true }, { variant: 'hero', states: [ 'default', 'hovered' ], withDarkMode: true }, { variant: 'header', states: [ 'default', 'hovered', 'selected' ], withDarkMode: true }, + { variant: 'radio_group', states: [ 'default', 'hovered', 'selected' ], withDarkMode: true }, ].forEach(({ variant, colorScheme, withDarkMode, states }) => { test.describe(`variant ${ variant }${ colorScheme ? ` with ${ colorScheme } color scheme` : '' }${ withDarkMode ? ' +@dark-mode' : '' }`, () => { test('', async({ render }) => { diff --git a/theme/components/Button/Button.ts b/theme/components/Button/Button.ts index e9482b8fbc..b43731816e 100644 --- a/theme/components/Button/Button.ts +++ b/theme/components/Button/Button.ts @@ -94,6 +94,42 @@ const variantOutline = defineStyle((props) => { }; }); +const variantRadioGroup = defineStyle((props) => { + const outline = runIfFn(variantOutline, props); + const bgColor = mode('blue.50', 'gray.800')(props); + const selectedTextColor = mode('blue.700', 'gray.50')(props); + + return { + ...outline, + fontWeight: 500, + cursor: 'pointer', + bgColor: 'none', + borderColor: bgColor, + _hover: { + borderColor: bgColor, + color: 'link_hovered', + }, + _active: { + bgColor: 'none', + }, + // We have a special state for this button variant that serves as a popover trigger. + // When any items (filters) are selected in the popover, the button should change its background and text color. + // The last CSS selector is for redefining styles for the TabList component. + [` + &[data-selected=true], + &[data-selected=true][aria-selected=true] + `]: { + cursor: 'initial', + bgColor, + borderColor: bgColor, + color: selectedTextColor, + _hover: { + color: selectedTextColor, + }, + }, + }; +}); + const variantSimple = defineStyle((props) => { const outline = runIfFn(variantOutline, props); @@ -223,6 +259,7 @@ const variants = { subtle: variantSubtle, hero: variantHero, header: variantHeader, + radio_group: variantRadioGroup, }; const baseStyle = defineStyle({ diff --git a/theme/components/Button/__screenshots__/Button.pw.tsx_dark-color-mode_variant-radio-group-dark-mode-1.png b/theme/components/Button/__screenshots__/Button.pw.tsx_dark-color-mode_variant-radio-group-dark-mode-1.png new file mode 100644 index 0000000000..8648ebecee Binary files /dev/null and b/theme/components/Button/__screenshots__/Button.pw.tsx_dark-color-mode_variant-radio-group-dark-mode-1.png differ diff --git a/theme/components/Button/__screenshots__/Button.pw.tsx_default_variant-radio-group-dark-mode-1.png b/theme/components/Button/__screenshots__/Button.pw.tsx_default_variant-radio-group-dark-mode-1.png new file mode 100644 index 0000000000..d26e938ccc Binary files /dev/null and b/theme/components/Button/__screenshots__/Button.pw.tsx_default_variant-radio-group-dark-mode-1.png differ diff --git a/theme/components/Tabs.ts b/theme/components/Tabs.ts index e73668761a..b07ade5e11 100644 --- a/theme/components/Tabs.ts +++ b/theme/components/Tabs.ts @@ -41,6 +41,33 @@ const variantOutline = definePartsStyle((props) => { }; }); +const variantRadioGroup = definePartsStyle((props) => { + return { + tab: { + ...Button.baseStyle, + ...Button.variants?.radio_group(props), + _selected: Button.variants?.radio_group(props)?.[` + &[data-selected=true], + &[data-selected=true][aria-selected=true] + `], + borderRadius: 'none', + _notFirst: { + borderLeftWidth: 0, + }, + '&[role="tab"]': { + _first: { + borderTopLeftRadius: 'base', + borderBottomLeftRadius: 'base', + }, + _last: { + borderTopRightRadius: 'base', + borderBottomRightRadius: 'base', + }, + }, + }, + }; +}); + const sizes = { sm: definePartsStyle({ tab: Button.sizes?.sm, @@ -53,6 +80,7 @@ const sizes = { const variants = { 'soft-rounded': variantSoftRounded, outline: variantOutline, + radio_group: variantRadioGroup, }; const Tabs = defineMultiStyleConfig({ diff --git a/types/api/contract.ts b/types/api/contract.ts index f2e1ad61d0..f1e937d866 100644 --- a/types/api/contract.ts +++ b/types/api/contract.ts @@ -143,3 +143,19 @@ export type SmartContractSecurityAuditSubmission = { 'audit_publish_date': string; 'comment'?: string; } + +// MUD SYSTEM + +export interface SmartContractMudSystemsResponse { + items: Array; +} + +export interface SmartContractMudSystemItem { + address: string; + name: string; +} + +export interface SmartContractMudSystemInfo { + name: string; + abi: Abi; +} diff --git a/types/client/multichainProviderConfig.ts b/types/client/multichainProviderConfig.ts index fbdced386f..8d4a695c69 100644 --- a/types/client/multichainProviderConfig.ts +++ b/types/client/multichainProviderConfig.ts @@ -2,5 +2,12 @@ export type MultichainProviderConfig = { name: string; dapp_id?: string; url_template: string; - logo?: string; + logo: string; +}; + +export type MultichainProviderConfigParsed = { + name: string; + logoUrl: string; + urlTemplate: string; + dappId?: string; }; diff --git a/types/utils.ts b/types/utils.ts index 6cb7a82094..cd48e6ec09 100644 --- a/types/utils.ts +++ b/types/utils.ts @@ -17,3 +17,6 @@ export type PickByType = Record< {[K in keyof T]: T[K] extends X ? K : never}[keyof T], X >; + +// Make some properties of an object optional +export type PartialBy = Omit & Partial> diff --git a/types/views/block.ts b/types/views/block.ts index 838dc523b7..c0324e508a 100644 --- a/types/views/block.ts +++ b/types/views/block.ts @@ -1,6 +1,7 @@ import type { ArrayElement } from 'types/utils'; export const BLOCK_FIELDS_IDS = [ + 'base_fee', 'burnt_fees', 'total_reward', 'nonce', diff --git a/ui/address/AddressContract.pwstory.tsx b/ui/address/AddressContract.pwstory.tsx index c558dd9ca2..b088e93fbc 100644 --- a/ui/address/AddressContract.pwstory.tsx +++ b/ui/address/AddressContract.pwstory.tsx @@ -2,8 +2,8 @@ import { useRouter } from 'next/router'; import React from 'react'; import useApiQuery from 'lib/api/useApiQuery'; -import useContractTabs from 'lib/hooks/useContractTabs'; import getQueryParamString from 'lib/router/getQueryParamString'; +import useContractTabs from 'ui/address/contract/useContractTabs'; import AddressContract from './AddressContract'; diff --git a/ui/address/__screenshots__/AddressTokens.pw.tsx_dark-color-mode_collections-dark-mode-1.png b/ui/address/__screenshots__/AddressTokens.pw.tsx_dark-color-mode_collections-dark-mode-1.png index 79c7e3e819..743da2862d 100644 Binary files a/ui/address/__screenshots__/AddressTokens.pw.tsx_dark-color-mode_collections-dark-mode-1.png and b/ui/address/__screenshots__/AddressTokens.pw.tsx_dark-color-mode_collections-dark-mode-1.png differ diff --git a/ui/address/__screenshots__/AddressTokens.pw.tsx_dark-color-mode_nfts-dark-mode-1.png b/ui/address/__screenshots__/AddressTokens.pw.tsx_dark-color-mode_nfts-dark-mode-1.png index ac0c8b5935..2490632952 100644 Binary files a/ui/address/__screenshots__/AddressTokens.pw.tsx_dark-color-mode_nfts-dark-mode-1.png and b/ui/address/__screenshots__/AddressTokens.pw.tsx_dark-color-mode_nfts-dark-mode-1.png differ diff --git a/ui/address/__screenshots__/AddressTokens.pw.tsx_default_collections-dark-mode-1.png b/ui/address/__screenshots__/AddressTokens.pw.tsx_default_collections-dark-mode-1.png index bbf9ed9894..2c9f8d372c 100644 Binary files a/ui/address/__screenshots__/AddressTokens.pw.tsx_default_collections-dark-mode-1.png and b/ui/address/__screenshots__/AddressTokens.pw.tsx_default_collections-dark-mode-1.png differ diff --git a/ui/address/__screenshots__/AddressTokens.pw.tsx_default_mobile-collections-1.png b/ui/address/__screenshots__/AddressTokens.pw.tsx_default_mobile-collections-1.png index b9975934e7..f2bce20aea 100644 Binary files a/ui/address/__screenshots__/AddressTokens.pw.tsx_default_mobile-collections-1.png and b/ui/address/__screenshots__/AddressTokens.pw.tsx_default_mobile-collections-1.png differ diff --git a/ui/address/__screenshots__/AddressTokens.pw.tsx_default_mobile-nfts-1.png b/ui/address/__screenshots__/AddressTokens.pw.tsx_default_mobile-nfts-1.png index fd147da3b8..50963d545a 100644 Binary files a/ui/address/__screenshots__/AddressTokens.pw.tsx_default_mobile-nfts-1.png and b/ui/address/__screenshots__/AddressTokens.pw.tsx_default_mobile-nfts-1.png differ diff --git a/ui/address/__screenshots__/AddressTokens.pw.tsx_default_nfts-dark-mode-1.png b/ui/address/__screenshots__/AddressTokens.pw.tsx_default_nfts-dark-mode-1.png index 93b1606fa8..013acf9a15 100644 Binary files a/ui/address/__screenshots__/AddressTokens.pw.tsx_default_nfts-dark-mode-1.png and b/ui/address/__screenshots__/AddressTokens.pw.tsx_default_nfts-dark-mode-1.png differ diff --git a/ui/address/contract/ContractCode.pw.tsx b/ui/address/contract/ContractCode.pw.tsx deleted file mode 100644 index 179f483513..0000000000 --- a/ui/address/contract/ContractCode.pw.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import React from 'react'; - -import * as addressMock from 'mocks/address/address'; -import { contractAudits } from 'mocks/contract/audits'; -import * as contractMock from 'mocks/contract/info'; -import { ENVS_MAP } from 'playwright/fixtures/mockEnvs'; -import * as socketServer from 'playwright/fixtures/socketServer'; -import { test, expect } from 'playwright/lib'; - -import ContractCode from './specs/ContractCode'; - -const hooksConfig = { - router: { - query: { hash: addressMock.contract.hash, tab: 'contract_code' }, - }, -}; - -// FIXME -// test cases which use socket cannot run in parallel since the socket server always run on the same port -test.describe.configure({ mode: 'serial' }); - -let addressApiUrl: string; - -test.beforeEach(async({ mockApiResponse, page }) => { - await page.route('https://cdn.jsdelivr.net/npm/monaco-editor@0.33.0/**', (route) => { - route.abort(); - }); - addressApiUrl = await mockApiResponse('address', addressMock.contract, { pathParams: { hash: addressMock.contract.hash } }); -}); - -test('full view +@mobile +@dark-mode', async({ render, mockApiResponse, createSocket }) => { - await mockApiResponse('contract', contractMock.withChangedByteCode, { pathParams: { hash: addressMock.contract.hash } }); - await mockApiResponse('contract', contractMock.withChangedByteCode, { pathParams: { hash: addressMock.contract.implementations?.[0].address as string } }); - - const component = await render(, { hooksConfig }, { withSocket: true }); - await createSocket(); - - await expect(component).toHaveScreenshot(); -}); - -test('verified with changed byte code socket', async({ render, mockApiResponse, createSocket }) => { - await mockApiResponse('contract', contractMock.verified, { pathParams: { hash: addressMock.contract.hash } }); - - const component = await render(, { hooksConfig }, { withSocket: true }); - const socket = await createSocket(); - const channel = await socketServer.joinChannel(socket, 'addresses:' + addressMock.contract.hash.toLowerCase()); - socketServer.sendMessage(socket, channel, 'changed_bytecode', {}); - - await expect(component).toHaveScreenshot(); -}); - -test('verified via lookup in eth_bytecode_db', async({ render, mockApiResponse, createSocket, page }) => { - const contractApiUrl = await mockApiResponse('contract', contractMock.nonVerified, { pathParams: { hash: addressMock.contract.hash } }); - await render(, { hooksConfig }, { withSocket: true }); - - const socket = await createSocket(); - const channel = await socketServer.joinChannel(socket, 'addresses:' + addressMock.contract.hash.toLowerCase()); - await page.waitForResponse(contractApiUrl); - socketServer.sendMessage(socket, channel, 'smart_contract_was_verified', {}); - const request = await page.waitForRequest(addressApiUrl); - - expect(request).toBeTruthy(); -}); - -test('verified with multiple sources', async({ render, page, mockApiResponse }) => { - await mockApiResponse('contract', contractMock.withMultiplePaths, { pathParams: { hash: addressMock.contract.hash } }); - await render(, { hooksConfig }, { withSocket: true }); - - const section = page.locator('section', { hasText: 'Contract source code' }); - await expect(section).toHaveScreenshot(); - - await page.getByRole('button', { name: 'View external libraries' }).click(); - await expect(section).toHaveScreenshot(); - - await page.getByRole('button', { name: 'Open source code in IDE' }).click(); - await expect(section).toHaveScreenshot(); -}); - -test('verified via sourcify', async({ render, mockApiResponse, page }) => { - await mockApiResponse('contract', contractMock.verifiedViaSourcify, { pathParams: { hash: addressMock.contract.hash } }); - await render(, { hooksConfig }, { withSocket: true }); - - await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 1200, height: 110 } }); -}); - -test('verified via eth bytecode db', async({ render, mockApiResponse, page }) => { - await mockApiResponse('contract', contractMock.verifiedViaEthBytecodeDb, { pathParams: { hash: addressMock.contract.hash } }); - await render(, { hooksConfig }, { withSocket: true }); - - await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 1200, height: 110 } }); -}); - -test('self destructed', async({ render, mockApiResponse, page }) => { - await mockApiResponse('contract', contractMock.selfDestructed, { pathParams: { hash: addressMock.contract.hash } }); - await render(, { hooksConfig }, { withSocket: true }); - - const section = page.locator('section', { hasText: 'Contract creation code' }); - await expect(section).toHaveScreenshot(); -}); - -test('with twin address alert +@mobile', async({ render, mockApiResponse }) => { - await mockApiResponse('contract', contractMock.withTwinAddress, { pathParams: { hash: addressMock.contract.hash } }); - const component = await render(, { hooksConfig }, { withSocket: true }); - - await expect(component.getByRole('alert')).toHaveScreenshot(); -}); - -test('with proxy address alert +@mobile', async({ render, mockApiResponse }) => { - await mockApiResponse('contract', contractMock.withProxyAddress, { pathParams: { hash: addressMock.contract.hash } }); - const component = await render(, { hooksConfig }, { withSocket: true }); - - await expect(component.getByRole('alert')).toHaveScreenshot(); -}); - -test('with certified icon +@mobile', async({ render, mockApiResponse, page }) => { - await mockApiResponse('contract', contractMock.certified, { pathParams: { hash: addressMock.contract.hash } }); - await render(, { hooksConfig }); - - await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 1200, height: 120 } }); -}); - -test('non verified', async({ render, mockApiResponse }) => { - await mockApiResponse('contract', contractMock.nonVerified, { pathParams: { hash: addressMock.contract.hash } }); - const component = await render(, { hooksConfig }, { withSocket: true }); - - await expect(component).toHaveScreenshot(); -}); - -test('zkSync contract', async({ render, mockApiResponse, page, mockEnvs }) => { - await mockEnvs(ENVS_MAP.zkSyncRollup); - await mockApiResponse('contract', contractMock.zkSync, { pathParams: { hash: addressMock.contract.hash } }); - await render(, { hooksConfig }, { withSocket: true }); - - await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 1200, height: 300 } }); -}); - -test.describe('with audits feature', () => { - - test.beforeEach(async({ mockEnvs }) => { - await mockEnvs(ENVS_MAP.hasContractAuditReports); - }); - - test('no audits', async({ render, mockApiResponse }) => { - await mockApiResponse('contract', contractMock.verified, { pathParams: { hash: addressMock.contract.hash } }); - await mockApiResponse('contract_security_audits', { items: [] }, { pathParams: { hash: addressMock.contract.hash } }); - const component = await render(, { hooksConfig }, { withSocket: true }); - - await expect(component).toHaveScreenshot(); - }); - - test('has audits', async({ render, mockApiResponse }) => { - await mockApiResponse('contract', contractMock.verified, { pathParams: { hash: addressMock.contract.hash } }); - await mockApiResponse('contract_security_audits', contractAudits, { pathParams: { hash: addressMock.contract.hash } }); - const component = await render(, { hooksConfig }, { withSocket: true }); - - await expect(component).toHaveScreenshot(); - }); -}); diff --git a/ui/address/contract/ContractCode.tsx b/ui/address/contract/ContractCode.tsx deleted file mode 100644 index a75f3a37fc..0000000000 --- a/ui/address/contract/ContractCode.tsx +++ /dev/null @@ -1,347 +0,0 @@ -import { Flex, Skeleton, Button, Grid, GridItem, Alert, chakra, Box, useColorModeValue } from '@chakra-ui/react'; -import type { UseQueryResult } from '@tanstack/react-query'; -import { useQueryClient } from '@tanstack/react-query'; -import type { Channel } from 'phoenix'; -import React from 'react'; - -import type { SocketMessage } from 'lib/socket/types'; -import type { Address as AddressInfo } from 'types/api/address'; -import type { SmartContract } from 'types/api/contract'; - -import { route } from 'nextjs-routes'; - -import config from 'configs/app'; -import type { ResourceError } from 'lib/api/resources'; -import { getResourceKey } from 'lib/api/useApiQuery'; -import { CONTRACT_LICENSES } from 'lib/contracts/licenses'; -import dayjs from 'lib/date/dayjs'; -import useSocketMessage from 'lib/socket/useSocketMessage'; -import ContractCertifiedLabel from 'ui/shared/ContractCertifiedLabel'; -import DataFetchAlert from 'ui/shared/DataFetchAlert'; -import AddressEntity from 'ui/shared/entities/address/AddressEntity'; -import Hint from 'ui/shared/Hint'; -import LinkExternal from 'ui/shared/links/LinkExternal'; -import LinkInternal from 'ui/shared/links/LinkInternal'; -import RawDataSnippet from 'ui/shared/RawDataSnippet'; - -import ContractCodeProxyPattern from './ContractCodeProxyPattern'; -import ContractSecurityAudits from './ContractSecurityAudits'; -import ContractSourceCode from './ContractSourceCode'; - -type Props = { - addressHash?: string; - contractQuery: UseQueryResult>; - channel: Channel | undefined; -} - -type InfoItemProps = { - label: string; - content: string | React.ReactNode; - className?: string; - isLoading: boolean; - hint?: string; -} - -const InfoItem = chakra(({ label, content, hint, className, isLoading }: InfoItemProps) => ( - - - - { label } - { hint && ( - - ) } - - - { content } - -)); - -const rollupFeature = config.features.rollup; - -const ContractCode = ({ addressHash, contractQuery, channel }: Props) => { - const [ isChangedBytecodeSocket, setIsChangedBytecodeSocket ] = React.useState(); - - const queryClient = useQueryClient(); - const addressInfo = queryClient.getQueryData(getResourceKey('address', { pathParams: { hash: addressHash } })); - - const { data, isPlaceholderData, isError } = contractQuery; - - const handleChangedBytecodeMessage: SocketMessage.AddressChangedBytecode['handler'] = React.useCallback(() => { - setIsChangedBytecodeSocket(true); - }, [ ]); - - const handleContractWasVerifiedMessage: SocketMessage.SmartContractWasVerified['handler'] = React.useCallback(() => { - queryClient.refetchQueries({ - queryKey: getResourceKey('address', { pathParams: { hash: addressHash } }), - }); - queryClient.refetchQueries({ - queryKey: getResourceKey('contract', { pathParams: { hash: addressHash } }), - }); - }, [ addressHash, queryClient ]); - - useSocketMessage({ - channel, - event: 'changed_bytecode', - handler: handleChangedBytecodeMessage, - }); - useSocketMessage({ - channel, - event: 'smart_contract_was_verified', - handler: handleContractWasVerifiedMessage, - }); - - if (isError) { - return ; - } - - const canBeVerified = !data?.is_self_destructed && !data?.is_verified; - - const verificationButton = isPlaceholderData ? ( - - ) : ( - - ); - - const licenseLink = (() => { - if (!data?.license_type) { - return null; - } - - const license = CONTRACT_LICENSES.find((license) => license.type === data.license_type); - if (!license || license.type === 'none') { - return null; - } - - return ( - - { license.label } - - ); - })(); - - const constructorArgs = (() => { - if (!data?.decoded_constructor_args) { - return data?.constructor_args; - } - - const decoded = data.decoded_constructor_args - .map(([ value, { name, type } ], index) => { - const valueEl = type === 'address' ? ( - - ) : { value }; - return ( - - Arg [{ index }] { name || '' } ({ type }): - { valueEl } - - ); - }); - - return ( - <> - { data.constructor_args } -

- { decoded } - - ); - })(); - - const verificationAlert = (() => { - if (data?.is_verified_via_eth_bytecode_db) { - return ( - - This contract has been { data.is_partially_verified ? 'partially ' : '' }verified using - - Blockscout Bytecode Database - - - ); - } - - if (data?.is_verified_via_sourcify) { - return ( - - This contract has been { data.is_partially_verified ? 'partially ' : '' }verified via Sourcify. - { data.sourcify_repo_url && View contract in Sourcify repository } - - ); - } - - return null; - })(); - - const contractNameWithCertifiedIcon = data?.is_verified ? ( - - { data.name } - { data.certified && } - - ) : null; - - return ( - <> - - { data?.is_blueprint && ( - - This is an - - ERC-5202 Blueprint contract - - - ) } - { data?.is_verified && ( - - - Contract Source Code Verified ({ data.is_partially_verified ? 'Partial' : 'Exact' } Match) - { data.is_partially_verified ? verificationButton : null } - - - ) } - { verificationAlert } - { (data?.is_changed_bytecode || isChangedBytecodeSocket) && ( - - Warning! Contract bytecode has been changed and does not match the verified one. Therefore, interaction with this smart contract may be risky. - - ) } - { !data?.is_verified && data?.verified_twin_address_hash && (!data?.proxy_type || data.proxy_type === 'unknown') && ( - - Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB - - All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with - - Verify & Publish - - page - - ) } - { data?.proxy_type && } - - { data?.is_verified && ( - - { data.name && } - { data.compiler_version && } - { data.zk_compiler_version && } - { data.evm_version && } - { licenseLink && ( - - ) } - { typeof data.optimization_enabled === 'boolean' && - } - { data.optimization_runs !== null && ( - - ) } - { data.verified_at && - } - { data.file_path && } - { config.UI.hasContractAuditReports && ( - } - isLoading={ isPlaceholderData } - /> - ) } - - ) } - - { constructorArgs && ( - - ) } - { data?.source_code && addressHash && ( - - ) } - { data?.compiler_settings ? ( - - ) : null } - { data?.abi && ( - - ) } - { data?.creation_bytecode && ( - - Contracts that self destruct in their constructors have no contract code published and cannot be verified. - Displaying the init data provided of the creating transaction. - - ) : null } - textareaMaxHeight="200px" - isLoading={ isPlaceholderData } - /> - ) } - { data?.deployed_bytecode && ( - - ) } - - - ); -}; - -export default ContractCode; diff --git a/ui/address/contract/ContractDetails.pw.tsx b/ui/address/contract/ContractDetails.pw.tsx new file mode 100644 index 0000000000..3f533710ae --- /dev/null +++ b/ui/address/contract/ContractDetails.pw.tsx @@ -0,0 +1,171 @@ +import React from 'react'; + +import * as addressMock from 'mocks/address/address'; +import * as contractMock from 'mocks/contract/info'; +import * as socketServer from 'playwright/fixtures/socketServer'; +import { test, expect } from 'playwright/lib'; +import * as pwConfig from 'playwright/utils/config'; + +import ContractDetails from './specs/ContractDetails'; + +const hooksConfig = { + router: { + query: { hash: addressMock.contract.hash, tab: 'contract_code' }, + }, +}; + +// FIXME +// test cases which use socket cannot run in parallel since the socket server always run on the same port +test.describe.configure({ mode: 'serial' }); + +let addressApiUrl: string; + +test.beforeEach(async({ mockApiResponse, page }) => { + await page.route('https://cdn.jsdelivr.net/npm/monaco-editor@0.33.0/**', (route) => { + route.abort(); + }); + addressApiUrl = await mockApiResponse('address', addressMock.contract, { pathParams: { hash: addressMock.contract.hash } }); +}); + +test.describe('full view', () => { + test.beforeEach(async({ mockApiResponse }) => { + await mockApiResponse('contract', contractMock.withChangedByteCode, { pathParams: { hash: addressMock.contract.hash } }); + await mockApiResponse('contract', contractMock.withChangedByteCode, { pathParams: { hash: addressMock.contract.implementations?.[0].address as string } }); + }); + + test('source code +@dark-mode', async({ render, createSocket }) => { + const hooksConfig = { + router: { + query: { hash: addressMock.contract.hash, tab: 'contract_source_code' }, + }, + }; + const component = await render(, { hooksConfig }, { withSocket: true }); + await createSocket(); + await expect(component).toHaveScreenshot(); + }); + + test('compiler', async({ render, createSocket }) => { + const hooksConfig = { + router: { + query: { hash: addressMock.contract.hash, tab: 'contract_compiler' }, + }, + }; + const component = await render(, { hooksConfig }, { withSocket: true }); + await createSocket(); + await expect(component).toHaveScreenshot(); + }); + + test('abi', async({ render, createSocket }) => { + const hooksConfig = { + router: { + query: { hash: addressMock.contract.hash, tab: 'contract_abi' }, + }, + }; + const component = await render(, { hooksConfig }, { withSocket: true }); + await createSocket(); + await expect(component).toHaveScreenshot(); + }); + + test('bytecode', async({ render, createSocket }) => { + const hooksConfig = { + router: { + query: { hash: addressMock.contract.hash, tab: 'contract_bytecode' }, + }, + }; + const component = await render(, { hooksConfig }, { withSocket: true }); + await createSocket(); + await expect(component).toHaveScreenshot(); + }); +}); + +test.describe('mobile view', () => { + test.use({ viewport: pwConfig.viewport.mobile }); + + test('source code', async({ render, createSocket, mockApiResponse }) => { + await mockApiResponse('contract', contractMock.withChangedByteCode, { pathParams: { hash: addressMock.contract.hash } }); + await mockApiResponse('contract', contractMock.withChangedByteCode, { pathParams: { hash: addressMock.contract.implementations?.[0].address as string } }); + const component = await render(, { hooksConfig }, { withSocket: true }); + await createSocket(); + await expect(component).toHaveScreenshot(); + }); +}); + +test('verified via lookup in eth_bytecode_db', async({ render, mockApiResponse, createSocket, page }) => { + const contractApiUrl = await mockApiResponse('contract', contractMock.nonVerified, { pathParams: { hash: addressMock.contract.hash } }); + await render(, { hooksConfig }, { withSocket: true }); + + const socket = await createSocket(); + const channel = await socketServer.joinChannel(socket, 'addresses:' + addressMock.contract.hash.toLowerCase()); + await page.waitForResponse(contractApiUrl); + socketServer.sendMessage(socket, channel, 'smart_contract_was_verified', {}); + const request = await page.waitForRequest(addressApiUrl); + + expect(request).toBeTruthy(); +}); + +test('verified with multiple sources', async({ render, page, mockApiResponse }) => { + await mockApiResponse('contract', contractMock.withMultiplePaths, { pathParams: { hash: addressMock.contract.hash } }); + await render(, { hooksConfig }, { withSocket: true }); + + const section = page.locator('section', { hasText: 'Contract source code' }); + await expect(section).toHaveScreenshot(); + + await page.getByRole('button', { name: 'View external libraries' }).click(); + await expect(section).toHaveScreenshot(); + + await page.getByRole('button', { name: 'Open source code in IDE' }).click(); + await expect(section).toHaveScreenshot(); +}); + +test('self destructed', async({ render, mockApiResponse, page }) => { + const hooksConfig = { + router: { + query: { hash: addressMock.contract.hash, tab: 'contract_bytecode' }, + }, + }; + await mockApiResponse('contract', contractMock.selfDestructed, { pathParams: { hash: addressMock.contract.hash } }); + await render(, { hooksConfig }, { withSocket: true }); + + const section = page.locator('section', { hasText: 'Contract creation code' }); + await expect(section).toHaveScreenshot(); +}); + +test('non verified', async({ render, mockApiResponse }) => { + await mockApiResponse('contract', contractMock.nonVerified, { pathParams: { hash: addressMock.contract.hash } }); + const component = await render(, { hooksConfig }, { withSocket: true }); + + await expect(component).toHaveScreenshot(); +}); + +test('implementation info', async({ render, mockApiResponse }) => { + const hooksConfig = { + router: { + query: { hash: addressMock.contract.hash, tab: 'contract_compiler' }, + }, + }; + + const implementationName = addressMock.contract.implementations?.[0].name as string; + const implementationAddress = addressMock.contract.implementations?.[0].address as string; + const implementationContract = { + ...contractMock.verified, + compiler_settings: { + evmVersion: 'london', + libraries: {}, + metadata: { + bytecodeHash: 'ipfs', + useLiteralContent: false, + }, + optimizer: { + enabled: true, + runs: 1000000, + }, + }, + }; + await mockApiResponse('contract', contractMock.verified, { pathParams: { hash: addressMock.contract.hash } }); + await mockApiResponse('contract', implementationContract, { pathParams: { hash: implementationAddress } }); + + const component = await render(, { hooksConfig }, { withSocket: true }); + await component.getByRole('combobox').selectOption(implementationName); + + await expect(component).toHaveScreenshot(); +}); diff --git a/ui/address/contract/ContractDetails.tsx b/ui/address/contract/ContractDetails.tsx new file mode 100644 index 0000000000..1dfc68b72d --- /dev/null +++ b/ui/address/contract/ContractDetails.tsx @@ -0,0 +1,123 @@ +import type { UseQueryResult } from '@tanstack/react-query'; +import { useQueryClient } from '@tanstack/react-query'; +import { useRouter } from 'next/router'; +import type { Channel } from 'phoenix'; +import React from 'react'; + +import type { SocketMessage } from 'lib/socket/types'; +import type { Address as AddressInfo } from 'types/api/address'; +import type { AddressImplementation } from 'types/api/addressParams'; +import type { SmartContract } from 'types/api/contract'; + +import type { ResourceError } from 'lib/api/resources'; +import useApiQuery, { getResourceKey } from 'lib/api/useApiQuery'; +import getQueryParamString from 'lib/router/getQueryParamString'; +import useSocketMessage from 'lib/socket/useSocketMessage'; +import * as stubs from 'stubs/contract'; +import DataFetchAlert from 'ui/shared/DataFetchAlert'; +import RoutedTabs from 'ui/shared/Tabs/RoutedTabs'; + +import ContractDetailsAlerts from './alerts/ContractDetailsAlerts'; +import ContractSourceAddressSelector from './ContractSourceAddressSelector'; +import ContractDetailsInfo from './info/ContractDetailsInfo'; +import useContractDetailsTabs from './useContractDetailsTabs'; + +const TAB_LIST_PROPS = { flexWrap: 'wrap', rowGap: 2 }; + +type Props = { + addressHash: string; + channel: Channel | undefined; + mainContractQuery: UseQueryResult; +} + +const ContractDetails = ({ addressHash, channel, mainContractQuery }: Props) => { + const router = useRouter(); + const sourceAddress = getQueryParamString(router.query.source_address); + + const queryClient = useQueryClient(); + const addressInfo = queryClient.getQueryData(getResourceKey('address', { pathParams: { hash: addressHash } })); + + const sourceItems: Array = React.useMemo(() => { + const currentAddressItem = { address: addressHash, name: addressInfo?.name || 'Contract' }; + if (!addressInfo || !addressInfo.implementations || addressInfo.implementations.length === 0) { + return [ currentAddressItem ]; + } + + return [ + currentAddressItem, + ...(addressInfo?.implementations.filter((item) => item.address !== addressHash && item.name) || []), + ]; + }, [ addressInfo, addressHash ]); + + const [ selectedItem, setSelectedItem ] = React.useState(sourceItems.find((item) => item.address === sourceAddress) || sourceItems[0]); + + const contractQuery = useApiQuery('contract', { + pathParams: { hash: selectedItem?.address }, + queryOptions: { + enabled: Boolean(selectedItem?.address), + refetchOnMount: false, + placeholderData: addressInfo?.is_verified ? stubs.CONTRACT_CODE_VERIFIED : stubs.CONTRACT_CODE_UNVERIFIED, + }, + }); + const { data, isPlaceholderData, isError } = contractQuery; + + const tabs = useContractDetailsTabs({ data, isLoading: isPlaceholderData, addressHash, sourceAddress: selectedItem.address }); + + const handleContractWasVerifiedMessage: SocketMessage.SmartContractWasVerified['handler'] = React.useCallback(() => { + queryClient.refetchQueries({ + queryKey: getResourceKey('address', { pathParams: { hash: addressHash } }), + }); + queryClient.refetchQueries({ + queryKey: getResourceKey('contract', { pathParams: { hash: addressHash } }), + }); + }, [ addressHash, queryClient ]); + + useSocketMessage({ + channel, + event: 'smart_contract_was_verified', + handler: handleContractWasVerifiedMessage, + }); + + if (isError) { + return ; + } + + const addressSelector = sourceItems.length > 1 ? ( + + ) : null; + + return ( + <> + + { mainContractQuery.data?.is_verified && ( + + ) } + + + ); +}; + +export default ContractDetails; diff --git a/ui/address/contract/ContractDetailsVerificationButton.tsx b/ui/address/contract/ContractDetailsVerificationButton.tsx new file mode 100644 index 0000000000..129f251f02 --- /dev/null +++ b/ui/address/contract/ContractDetailsVerificationButton.tsx @@ -0,0 +1,39 @@ +import { Button, Skeleton } from '@chakra-ui/react'; +import React from 'react'; + +import { route } from 'nextjs-routes'; + +interface Props { + isLoading: boolean; + addressHash: string; + isPartiallyVerified: boolean; +} + +const ContractDetailsVerificationButton = ({ isLoading, addressHash, isPartiallyVerified }: Props) => { + if (isLoading) { + return ( + + ); + } + return ( + + ); +}; + +export default React.memo(ContractDetailsVerificationButton); diff --git a/ui/address/contract/ContractSourceAddressSelector.tsx b/ui/address/contract/ContractSourceAddressSelector.tsx new file mode 100644 index 0000000000..31fd271f42 --- /dev/null +++ b/ui/address/contract/ContractSourceAddressSelector.tsx @@ -0,0 +1,80 @@ +import { chakra, Flex, Select, Skeleton } from '@chakra-ui/react'; +import React from 'react'; + +import { route } from 'nextjs-routes'; + +import CopyToClipboard from 'ui/shared/CopyToClipboard'; +import AddressEntity from 'ui/shared/entities/address/AddressEntity'; +import LinkNewTab from 'ui/shared/links/LinkNewTab'; + +export interface Item { + address: string; + name?: string | null | undefined; +} + +interface Props { + className?: string; + label: string; + selectedItem: Item; + onItemSelect: (item: Item) => void; + items: Array; + isLoading?: boolean; +} + +const ContractSourceAddressSelector = ({ className, selectedItem, onItemSelect, items, isLoading, label }: Props) => { + + const handleItemSelect = React.useCallback((event: React.ChangeEvent) => { + const nextOption = items.find(({ address }) => address === event.target.value); + if (nextOption) { + onItemSelect(nextOption); + } + }, [ items, onItemSelect ]); + + if (isLoading) { + return ; + } + + if (items.length === 0) { + return null; + } + + if (items.length === 1) { + return ( + + { label } + + + ); + } + + return ( + + { label } + + + + + + + ); +}; + +export default React.memo(chakra(ContractSourceAddressSelector)); diff --git a/ui/address/contract/ContractSourceCode.tsx b/ui/address/contract/ContractSourceCode.tsx index e1ca2acd28..001de780da 100644 --- a/ui/address/contract/ContractSourceCode.tsx +++ b/ui/address/contract/ContractSourceCode.tsx @@ -1,13 +1,10 @@ -import { Flex, Select, Skeleton, Text, Tooltip } from '@chakra-ui/react'; +import { Flex, Skeleton, Text, Tooltip } from '@chakra-ui/react'; import React from 'react'; -import type { AddressImplementation } from 'types/api/addressParams'; import type { SmartContract } from 'types/api/contract'; import { route } from 'nextjs-routes'; -import useApiQuery from 'lib/api/useApiQuery'; -import * as stubs from 'stubs/contract'; import CopyToClipboard from 'ui/shared/CopyToClipboard'; import LinkInternal from 'ui/shared/links/LinkInternal'; import CodeEditor from 'ui/shared/monaco/CodeEditor'; @@ -38,82 +35,34 @@ function getEditorData(contractInfo: SmartContract | undefined) { ]; } -interface SourceContractOption { - address: string; - label: string; -} - interface Props { - address: string; - implementations?: Array; + data: SmartContract | undefined; + sourceAddress: string; + isLoading?: boolean; } -export const ContractSourceCode = ({ address, implementations }: Props) => { - - const options: Array = React.useMemo(() => { - return [ - { label: 'Proxy', address }, - ...(implementations || []) - .filter((item) => item.name && item.address !== address) - .map(({ name, address }, item, array) => ({ address, label: array.length === 1 ? 'Implementation' : `Impl: ${ name }` })), - ]; - }, [ address, implementations ]); - - const [ sourceContract, setSourceContract ] = React.useState(options[0]); - - const contractQuery = useApiQuery('contract', { - pathParams: { hash: sourceContract.address }, - queryOptions: { - refetchOnMount: false, - placeholderData: stubs.CONTRACT_CODE_VERIFIED, - }, - }); +export const ContractSourceCode = ({ data, isLoading, sourceAddress }: Props) => { const editorData = React.useMemo(() => { - return getEditorData(contractQuery.data); - }, [ contractQuery.data ]); - - const isLoading = contractQuery.isPlaceholderData; - - const handleSelectChange = React.useCallback((event: React.ChangeEvent) => { - const nextOption = options.find(({ address }) => address === event.target.value); - if (nextOption) { - setSourceContract(nextOption); - } - }, [ options ]); + return getEditorData(data); + }, [ data ]); const heading = ( Contract source code - { contractQuery.data?.language && - ({ contractQuery.data.language }) } + { data?.language && + ({ data.language }) } ); - const select = options.length > 1 ? ( - - ) : null; - - const externalLibraries = contractQuery.data?.external_libraries ? - : + const externalLibraries = data?.external_libraries ? + : null; - const diagramLink = contractQuery?.data?.can_be_visualized_via_sol2uml ? ( + const diagramLink = data?.can_be_visualized_via_sol2uml ? ( @@ -124,11 +73,11 @@ export const ContractSourceCode = ({ address, implementations }: Props) => { ) : null; - const ides = ; + const ides = ; - const copyToClipboard = contractQuery.data && editorData?.length === 1 ? ( + const copyToClipboard = data && editorData?.length === 1 ? ( @@ -146,13 +95,13 @@ export const ContractSourceCode = ({ address, implementations }: Props) => { return ( ); })(); @@ -161,7 +110,6 @@ export const ContractSourceCode = ({ address, implementations }: Props) => {
{ heading } - { select } { externalLibraries } { diagramLink } { ides } diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_dark-color-mode_full-view-mobile-dark-mode-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_dark-color-mode_full-view-mobile-dark-mode-1.png deleted file mode 100644 index 3db7025fd4..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_dark-color-mode_full-view-mobile-dark-mode-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_full-view-mobile-dark-mode-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_full-view-mobile-dark-mode-1.png deleted file mode 100644 index 2108d45306..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_full-view-mobile-dark-mode-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-via-eth-bytecode-db-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-via-eth-bytecode-db-1.png deleted file mode 100644 index 3582332da3..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-via-eth-bytecode-db-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-via-sourcify-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-via-sourcify-1.png deleted file mode 100644 index b797261a7a..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-via-sourcify-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-changed-byte-code-socket-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-changed-byte-code-socket-1.png deleted file mode 100644 index 241191634a..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-changed-byte-code-socket-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-multiple-sources-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-multiple-sources-1.png deleted file mode 100644 index bb3d1162ac..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-multiple-sources-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-multiple-sources-2.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-multiple-sources-2.png deleted file mode 100644 index faed372ebc..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-multiple-sources-2.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-multiple-sources-3.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-multiple-sources-3.png deleted file mode 100644 index 7d9285311e..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_verified-with-multiple-sources-3.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-audits-feature-has-audits-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-audits-feature-has-audits-1.png deleted file mode 100644 index 8a0b09c4ea..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-audits-feature-has-audits-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-audits-feature-no-audits-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-audits-feature-no-audits-1.png deleted file mode 100644 index 1601567f2c..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-audits-feature-no-audits-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-certified-icon-mobile-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-certified-icon-mobile-1.png deleted file mode 100644 index 9d405d4a33..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-certified-icon-mobile-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-proxy-address-alert-mobile-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-proxy-address-alert-mobile-1.png deleted file mode 100644 index a73642ee31..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-proxy-address-alert-mobile-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-twin-address-alert-mobile-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-twin-address-alert-mobile-1.png deleted file mode 100644 index 39196cf219..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_with-twin-address-alert-mobile-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_zkSync-contract-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_zkSync-contract-1.png deleted file mode 100644 index 62b1522862..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_zkSync-contract-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_full-view-mobile-dark-mode-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_full-view-mobile-dark-mode-1.png deleted file mode 100644 index 3f5ad28058..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_full-view-mobile-dark-mode-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_with-certified-icon-mobile-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_with-certified-icon-mobile-1.png deleted file mode 100644 index 964b95edd1..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_with-certified-icon-mobile-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_with-proxy-address-alert-mobile-1.png b/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_with-proxy-address-alert-mobile-1.png deleted file mode 100644 index 5cccb20269..0000000000 Binary files a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_with-proxy-address-alert-mobile-1.png and /dev/null differ diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_dark-color-mode_full-view-source-code-dark-mode-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_dark-color-mode_full-view-source-code-dark-mode-1.png new file mode 100644 index 0000000000..d5b3fd8417 Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_dark-color-mode_full-view-source-code-dark-mode-1.png differ diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-abi-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-abi-1.png new file mode 100644 index 0000000000..e95cf672f7 Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-abi-1.png differ diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-bytecode-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-bytecode-1.png new file mode 100644 index 0000000000..d23ffb336f Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-bytecode-1.png differ diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-compiler-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-compiler-1.png new file mode 100644 index 0000000000..86101f81ab Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-compiler-1.png differ diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-source-code-dark-mode-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-source-code-dark-mode-1.png new file mode 100644 index 0000000000..eb47124dde Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-source-code-dark-mode-1.png differ diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_implementation-info-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_implementation-info-1.png new file mode 100644 index 0000000000..89a3ba5a9f Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_implementation-info-1.png differ diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_mobile-view-source-code-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_mobile-view-source-code-1.png new file mode 100644 index 0000000000..58edaeecc6 Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_mobile-view-source-code-1.png differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_non-verified-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_non-verified-1.png similarity index 100% rename from ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_non-verified-1.png rename to ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_non-verified-1.png diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_self-destructed-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_self-destructed-1.png similarity index 100% rename from ui/address/contract/__screenshots__/ContractCode.pw.tsx_default_self-destructed-1.png rename to ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_self-destructed-1.png diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_verified-with-multiple-sources-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_verified-with-multiple-sources-1.png new file mode 100644 index 0000000000..ff1e2c3f22 Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_verified-with-multiple-sources-1.png differ diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_verified-with-multiple-sources-2.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_verified-with-multiple-sources-2.png new file mode 100644 index 0000000000..f8797dce50 Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_verified-with-multiple-sources-2.png differ diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_verified-with-multiple-sources-3.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_verified-with-multiple-sources-3.png new file mode 100644 index 0000000000..a858f0dd54 Binary files /dev/null and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_verified-with-multiple-sources-3.png differ diff --git a/ui/address/contract/ContractCodeProxyPattern.pw.tsx b/ui/address/contract/alerts/ContractDetailsAlertProxyPattern.pw.tsx similarity index 54% rename from ui/address/contract/ContractCodeProxyPattern.pw.tsx rename to ui/address/contract/alerts/ContractDetailsAlertProxyPattern.pw.tsx index a2e97768c0..e6e4134db4 100644 --- a/ui/address/contract/ContractCodeProxyPattern.pw.tsx +++ b/ui/address/contract/alerts/ContractDetailsAlertProxyPattern.pw.tsx @@ -2,19 +2,19 @@ import React from 'react'; import { test, expect } from 'playwright/lib'; -import ContractCodeProxyPattern from './ContractCodeProxyPattern'; +import ContractDetailsAlertProxyPattern from './ContractDetailsAlertProxyPattern'; test('proxy type with link +@mobile', async({ render }) => { - const component = await render(); + const component = await render(); await expect(component).toHaveScreenshot(); }); test('proxy type with link but without description', async({ render }) => { - const component = await render(); + const component = await render(); await expect(component).toHaveScreenshot(); }); test('proxy type without link', async({ render }) => { - const component = await render(); + const component = await render(); await expect(component).toHaveScreenshot(); }); diff --git a/ui/address/contract/ContractCodeProxyPattern.tsx b/ui/address/contract/alerts/ContractDetailsAlertProxyPattern.tsx similarity index 100% rename from ui/address/contract/ContractCodeProxyPattern.tsx rename to ui/address/contract/alerts/ContractDetailsAlertProxyPattern.tsx diff --git a/ui/address/contract/alerts/ContractDetailsAlertVerificationSource.tsx b/ui/address/contract/alerts/ContractDetailsAlertVerificationSource.tsx new file mode 100644 index 0000000000..292a1f7b7e --- /dev/null +++ b/ui/address/contract/alerts/ContractDetailsAlertVerificationSource.tsx @@ -0,0 +1,39 @@ +import { Alert } from '@chakra-ui/react'; +import React from 'react'; + +import type { SmartContract } from 'types/api/contract'; + +import LinkExternal from 'ui/shared/links/LinkExternal'; + +interface Props { + data: SmartContract | undefined; +} + +const ContractDetailsAlertVerificationSource = ({ data }: Props) => { + if (data?.is_verified_via_eth_bytecode_db) { + return ( + + This contract has been { data.is_partially_verified ? 'partially ' : '' }verified using + + Blockscout Bytecode Database + + + ); + } + + if (data?.is_verified_via_sourcify) { + return ( + + This contract has been { data.is_partially_verified ? 'partially ' : '' }verified via Sourcify. + { data.sourcify_repo_url && View contract in Sourcify repository } + + ); + } + + return null; +}; + +export default React.memo(ContractDetailsAlertVerificationSource); diff --git a/ui/address/contract/alerts/ContractDetailsAlerts.pw.tsx b/ui/address/contract/alerts/ContractDetailsAlerts.pw.tsx new file mode 100644 index 0000000000..52fd35fe4c --- /dev/null +++ b/ui/address/contract/alerts/ContractDetailsAlerts.pw.tsx @@ -0,0 +1,59 @@ +import React from 'react'; + +import * as addressMock from 'mocks/address/address'; +import * as contractMock from 'mocks/contract/info'; +import * as socketServer from 'playwright/fixtures/socketServer'; +import { test, expect } from 'playwright/lib'; + +import ContractDetailsAlerts from './ContractDetailsAlerts.pwstory'; + +// FIXME +// test cases which use socket cannot run in parallel since the socket server always run on the same port +test.describe.configure({ mode: 'serial' }); + +test('verified with changed byte code socket', async({ render, createSocket }) => { + const props = { + data: contractMock.verified, + isLoading: false, + addressHash: addressMock.contract.hash, + }; + const component = await render(, undefined, { withSocket: true }); + const socket = await createSocket(); + const channel = await socketServer.joinChannel(socket, 'addresses:' + addressMock.contract.hash.toLowerCase()); + socketServer.sendMessage(socket, channel, 'changed_bytecode', {}); + + await expect(component).toHaveScreenshot(); +}); + +test('verified via sourcify', async({ render }) => { + const props = { + data: contractMock.verifiedViaSourcify, + isLoading: false, + addressHash: addressMock.contract.hash, + }; + const component = await render(, undefined, { withSocket: true }); + + await expect(component).toHaveScreenshot(); +}); + +test('verified via eth bytecode db', async({ render }) => { + const props = { + data: contractMock.verifiedViaEthBytecodeDb, + isLoading: false, + addressHash: addressMock.contract.hash, + }; + const component = await render(, undefined, { withSocket: true }); + + await expect(component).toHaveScreenshot(); +}); + +test('with twin address alert +@mobile', async({ render }) => { + const props = { + data: contractMock.withTwinAddress, + isLoading: false, + addressHash: addressMock.contract.hash, + }; + const component = await render(, undefined, { withSocket: true }); + + await expect(component).toHaveScreenshot(); +}); diff --git a/ui/address/contract/alerts/ContractDetailsAlerts.pwstory.tsx b/ui/address/contract/alerts/ContractDetailsAlerts.pwstory.tsx new file mode 100644 index 0000000000..e7fea90322 --- /dev/null +++ b/ui/address/contract/alerts/ContractDetailsAlerts.pwstory.tsx @@ -0,0 +1,17 @@ +import React from 'react'; + +import useSocketChannel from 'lib/socket/useSocketChannel'; + +import type { Props } from './ContractDetailsAlerts'; +import ContractDetailsAlerts from './ContractDetailsAlerts'; + +const ContractDetailsAlertsPwStory = (props: Props) => { + const channel = useSocketChannel({ + topic: `addresses:${ props.addressHash.toLowerCase() }`, + isDisabled: false, + }); + + return ; +}; + +export default ContractDetailsAlertsPwStory; diff --git a/ui/address/contract/alerts/ContractDetailsAlerts.tsx b/ui/address/contract/alerts/ContractDetailsAlerts.tsx new file mode 100644 index 0000000000..ed040c94a1 --- /dev/null +++ b/ui/address/contract/alerts/ContractDetailsAlerts.tsx @@ -0,0 +1,92 @@ +import { chakra, Alert, Box, Flex, Skeleton } from '@chakra-ui/react'; +import type { Channel } from 'phoenix'; +import React from 'react'; + +import type { SocketMessage } from 'lib/socket/types'; +import type { SmartContract } from 'types/api/contract'; + +import { route } from 'nextjs-routes'; + +import useSocketMessage from 'lib/socket/useSocketMessage'; +import AddressEntity from 'ui/shared/entities/address/AddressEntity'; +import LinkExternal from 'ui/shared/links/LinkExternal'; +import LinkInternal from 'ui/shared/links/LinkInternal'; + +import ContractDetailsVerificationButton from '../ContractDetailsVerificationButton'; +import ContractDetailsAlertProxyPattern from './ContractDetailsAlertProxyPattern'; +import ContractDetailsAlertVerificationSource from './ContractDetailsAlertVerificationSource'; + +export interface Props { + data: SmartContract | undefined; + isLoading: boolean; + addressHash: string; + channel?: Channel; +} + +const ContractDetailsAlerts = ({ data, isLoading, addressHash, channel }: Props) => { + const [ isChangedBytecodeSocket, setIsChangedBytecodeSocket ] = React.useState(); + + const handleChangedBytecodeMessage: SocketMessage.AddressChangedBytecode['handler'] = React.useCallback(() => { + setIsChangedBytecodeSocket(true); + }, [ ]); + + useSocketMessage({ + channel, + event: 'changed_bytecode', + handler: handleChangedBytecodeMessage, + }); + + return ( + + { data?.is_blueprint && ( + + This is an + + ERC-5202 Blueprint contract + + + ) } + { data?.is_verified && ( + + + Contract Source Code Verified ({ data.is_partially_verified ? 'Partial' : 'Exact' } Match) + { + data.is_partially_verified ? ( + + ) : null + } + + + ) } + + { (data?.is_changed_bytecode || isChangedBytecodeSocket) && ( + + Warning! Contract bytecode has been changed and does not match the verified one. Therefore, interaction with this smart contract may be risky. + + ) } + { !data?.is_verified && data?.verified_twin_address_hash && (!data?.proxy_type || data.proxy_type === 'unknown') && ( + + Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB + + All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with + + Verify & Publish + + page + + ) } + { data?.proxy_type && } + + ); +}; + +export default React.memo(ContractDetailsAlerts); diff --git a/ui/address/contract/__screenshots__/ContractCodeProxyPattern.pw.tsx_default_proxy-type-with-link-but-without-description-1.png b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlertProxyPattern.pw.tsx_default_proxy-type-with-link-but-without-description-1.png similarity index 100% rename from ui/address/contract/__screenshots__/ContractCodeProxyPattern.pw.tsx_default_proxy-type-with-link-but-without-description-1.png rename to ui/address/contract/alerts/__screenshots__/ContractDetailsAlertProxyPattern.pw.tsx_default_proxy-type-with-link-but-without-description-1.png diff --git a/ui/address/contract/__screenshots__/ContractCodeProxyPattern.pw.tsx_default_proxy-type-with-link-mobile-1.png b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlertProxyPattern.pw.tsx_default_proxy-type-with-link-mobile-1.png similarity index 100% rename from ui/address/contract/__screenshots__/ContractCodeProxyPattern.pw.tsx_default_proxy-type-with-link-mobile-1.png rename to ui/address/contract/alerts/__screenshots__/ContractDetailsAlertProxyPattern.pw.tsx_default_proxy-type-with-link-mobile-1.png diff --git a/ui/address/contract/__screenshots__/ContractCodeProxyPattern.pw.tsx_default_proxy-type-without-link-1.png b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlertProxyPattern.pw.tsx_default_proxy-type-without-link-1.png similarity index 100% rename from ui/address/contract/__screenshots__/ContractCodeProxyPattern.pw.tsx_default_proxy-type-without-link-1.png rename to ui/address/contract/alerts/__screenshots__/ContractDetailsAlertProxyPattern.pw.tsx_default_proxy-type-without-link-1.png diff --git a/ui/address/contract/__screenshots__/ContractCodeProxyPattern.pw.tsx_mobile_proxy-type-with-link-mobile-1.png b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlertProxyPattern.pw.tsx_mobile_proxy-type-with-link-mobile-1.png similarity index 100% rename from ui/address/contract/__screenshots__/ContractCodeProxyPattern.pw.tsx_mobile_proxy-type-with-link-mobile-1.png rename to ui/address/contract/alerts/__screenshots__/ContractDetailsAlertProxyPattern.pw.tsx_mobile_proxy-type-with-link-mobile-1.png diff --git a/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_verified-via-eth-bytecode-db-1.png b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_verified-via-eth-bytecode-db-1.png new file mode 100644 index 0000000000..26e63d6237 Binary files /dev/null and b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_verified-via-eth-bytecode-db-1.png differ diff --git a/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_verified-via-sourcify-1.png b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_verified-via-sourcify-1.png new file mode 100644 index 0000000000..8b724d0b27 Binary files /dev/null and b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_verified-via-sourcify-1.png differ diff --git a/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_verified-with-changed-byte-code-socket-1.png b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_verified-with-changed-byte-code-socket-1.png new file mode 100644 index 0000000000..72e319a01d Binary files /dev/null and b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_verified-with-changed-byte-code-socket-1.png differ diff --git a/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_with-twin-address-alert-mobile-1.png b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_with-twin-address-alert-mobile-1.png new file mode 100644 index 0000000000..ad8070659c Binary files /dev/null and b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_default_with-twin-address-alert-mobile-1.png differ diff --git a/ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_with-twin-address-alert-mobile-1.png b/ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_mobile_with-twin-address-alert-mobile-1.png similarity index 100% rename from ui/address/contract/__screenshots__/ContractCode.pw.tsx_mobile_with-twin-address-alert-mobile-1.png rename to ui/address/contract/alerts/__screenshots__/ContractDetailsAlerts.pw.tsx_mobile_with-twin-address-alert-mobile-1.png diff --git a/ui/address/contract/ContractSecurityAudits.tsx b/ui/address/contract/audits/ContractSecurityAudits.tsx similarity index 95% rename from ui/address/contract/ContractSecurityAudits.tsx rename to ui/address/contract/audits/ContractSecurityAudits.tsx index ce6e2fc9b3..983ddb9bb6 100644 --- a/ui/address/contract/ContractSecurityAudits.tsx +++ b/ui/address/contract/audits/ContractSecurityAudits.tsx @@ -9,7 +9,7 @@ import ContainerWithScrollY from 'ui/shared/ContainerWithScrollY'; import FormModal from 'ui/shared/FormModal'; import LinkExternal from 'ui/shared/links/LinkExternal'; -import ContractSubmitAuditForm from './contractSubmitAuditForm/ContractSubmitAuditForm'; +import ContractSubmitAuditForm from './ContractSubmitAuditForm'; type Props = { addressHash?: string; diff --git a/ui/address/contract/contractSubmitAuditForm/ContractSubmitAuditForm.pw.tsx b/ui/address/contract/audits/ContractSubmitAuditForm.pw.tsx similarity index 100% rename from ui/address/contract/contractSubmitAuditForm/ContractSubmitAuditForm.pw.tsx rename to ui/address/contract/audits/ContractSubmitAuditForm.pw.tsx diff --git a/ui/address/contract/contractSubmitAuditForm/ContractSubmitAuditForm.tsx b/ui/address/contract/audits/ContractSubmitAuditForm.tsx similarity index 55% rename from ui/address/contract/contractSubmitAuditForm/ContractSubmitAuditForm.tsx rename to ui/address/contract/audits/ContractSubmitAuditForm.tsx index b03d4884cc..d64372a77f 100644 --- a/ui/address/contract/contractSubmitAuditForm/ContractSubmitAuditForm.tsx +++ b/ui/address/contract/audits/ContractSubmitAuditForm.tsx @@ -1,23 +1,18 @@ import { Button, VStack } from '@chakra-ui/react'; import React from 'react'; import type { SubmitHandler } from 'react-hook-form'; -import { useForm } from 'react-hook-form'; +import { FormProvider, useForm } from 'react-hook-form'; import type { SmartContractSecurityAuditSubmission } from 'types/api/contract'; import type { ResourceError } from 'lib/api/resources'; import useApiFetch from 'lib/api/useApiFetch'; +import dayjs from 'lib/date/dayjs'; import useToast from 'lib/hooks/useToast'; - -import AuditComment from './fields/AuditComment'; -import AuditCompanyName from './fields/AuditCompanyName'; -import AuditProjectName from './fields/AuditProjectName'; -import AuditProjectUrl from './fields/AuditProjectUrl'; -import AuditReportDate from './fields/AuditReportDate'; -import AuditReportUrl from './fields/AuditReportUrl'; -import AuditSubmitterEmail from './fields/AuditSubmitterEmail'; -import AuditSubmitterIsOwner from './fields/AuditSubmitterIsOwner'; -import AuditSubmitterName from './fields/AuditSubmitterName'; +import FormFieldCheckbox from 'ui/shared/forms/fields/FormFieldCheckbox'; +import FormFieldEmail from 'ui/shared/forms/fields/FormFieldEmail'; +import FormFieldText from 'ui/shared/forms/fields/FormFieldText'; +import FormFieldUrl from 'ui/shared/forms/fields/FormFieldUrl'; interface Props { address?: string; @@ -46,10 +41,11 @@ const ContractSubmitAuditForm = ({ address, onSuccess }: Props) => { const apiFetch = useApiFetch(); const toast = useToast(); - const { handleSubmit, formState, control, setError } = useForm({ + const formApi = useForm({ mode: 'onTouched', defaultValues: { is_project_owner: false }, }); + const { handleSubmit, formState, setError } = formApi; const onFormSubmit: SubmitHandler = React.useCallback(async(data) => { try { @@ -94,30 +90,46 @@ const ContractSubmitAuditForm = ({ address, onSuccess }: Props) => { }, [ apiFetch, address, toast, setError, onSuccess ]); return ( -
- - - - - - - - - - - - - -
+ + + ); }; diff --git a/ui/address/contract/contractSubmitAuditForm/__screenshots__/ContractSubmitAuditForm.pw.tsx_default_base-view-1.png b/ui/address/contract/audits/__screenshots__/ContractSubmitAuditForm.pw.tsx_default_base-view-1.png similarity index 100% rename from ui/address/contract/contractSubmitAuditForm/__screenshots__/ContractSubmitAuditForm.pw.tsx_default_base-view-1.png rename to ui/address/contract/audits/__screenshots__/ContractSubmitAuditForm.pw.tsx_default_base-view-1.png diff --git a/ui/address/contract/contractSubmitAuditForm/fields/AuditComment.tsx b/ui/address/contract/contractSubmitAuditForm/fields/AuditComment.tsx deleted file mode 100644 index 918a496dea..0000000000 --- a/ui/address/contract/contractSubmitAuditForm/fields/AuditComment.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { FormControl, Textarea } from '@chakra-ui/react'; -import React from 'react'; -import type { Control, ControllerProps } from 'react-hook-form'; -import { Controller } from 'react-hook-form'; - -import InputPlaceholder from 'ui/shared/InputPlaceholder'; - -import type { Inputs } from '../ContractSubmitAuditForm'; - -interface Props { - control: Control; -} - -const AuditComment = ({ control }: Props) => { - const renderControl: ControllerProps['render'] = React.useCallback(({ field, fieldState }) => { - return ( - -